nsswitch/idmap_ldap.c

説明を見る。
00001 /*
00002    Unix SMB/CIFS implementation.
00003 
00004    idmap LDAP backend
00005 
00006    Copyright (C) Tim Potter             2000
00007    Copyright (C) Jim McDonough <jmcd@us.ibm.com>        2003
00008    Copyright (C) Gerald Carter          2003
00009    Copyright (C) Simo Sorce             2003-2007
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; either version 2 of the License, or
00014    (at your option) any later version.
00015 
00016    This program is distributed in the hope that it will be useful,
00017    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019    GNU General Public License for more details.
00020 
00021    You should have received a copy of the GNU General Public License
00022    along with this program; if not, write to the Free Software
00023    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00024 */
00025 
00026 #include "includes.h"
00027 
00028 #undef DBGC_CLASS
00029 #define DBGC_CLASS DBGC_IDMAP
00030 
00031 #include <lber.h>
00032 #include <ldap.h>
00033 
00034 #include "smbldap.h"
00035 
00036 struct idmap_ldap_context {
00037         struct smbldap_state *smbldap_state;
00038         char *url;
00039         char *suffix;
00040         char *user_dn;
00041         uint32_t filter_low_id, filter_high_id;         /* Filter range */
00042         BOOL anon;
00043 };
00044 
00045 struct idmap_ldap_alloc_context {
00046         struct smbldap_state *smbldap_state;
00047         char *url;
00048         char *suffix;
00049         char *user_dn;
00050         uid_t low_uid, high_uid;      /* Range of uids */
00051         gid_t low_gid, high_gid;      /* Range of gids */
00052 
00053 };
00054 
00055 #define CHECK_ALLOC_DONE(mem) do { \
00056         if (!mem) { \
00057                 DEBUG(0, ("Out of memory!\n")); \
00058                 ret = NT_STATUS_NO_MEMORY; \
00059                 goto done; \
00060         } } while (0)
00061 
00062 /**********************************************************************
00063  IDMAP ALLOC TDB BACKEND
00064 **********************************************************************/
00065 
00066 static struct idmap_ldap_alloc_context *idmap_alloc_ldap;
00067 
00068 /*********************************************************************
00069  ********************************************************************/
00070 
00071 static NTSTATUS get_credentials( TALLOC_CTX *mem_ctx,
00072                                  struct smbldap_state *ldap_state,
00073                                  const char *config_option,
00074                                  struct idmap_domain *dom,
00075                                  char **dn )
00076 {
00077         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
00078         char *secret = NULL;
00079         const char *tmp = NULL;
00080         char *user_dn = NULL;
00081         BOOL anon = False;
00082 
00083         /* assume anonymous if we don't have a specified user */
00084 
00085         tmp = lp_parm_const_string(-1, config_option, "ldap_user_dn", NULL);
00086 
00087         if ( tmp ) {
00088                 if (!dom) {
00089                         /* only the alloc backend can pass in a NULL dom */
00090                         secret = idmap_fetch_secret("ldap", True,
00091                                                     NULL, tmp);
00092                 } else {
00093                         secret = idmap_fetch_secret("ldap", False,
00094                                                     dom->name, tmp);
00095                 }
00096 
00097                 if (!secret) {
00098                         DEBUG(0, ("get_credentials: Unable to fetch "
00099                                   "auth credentials for %s in %s\n",
00100                                   tmp, (dom==NULL)?"ALLOC":dom->name));
00101                         ret = NT_STATUS_ACCESS_DENIED;
00102                         goto done;
00103                 }
00104                 *dn = talloc_strdup(mem_ctx, tmp);
00105                 CHECK_ALLOC_DONE(*dn);
00106         } else {
00107                 if (!fetch_ldap_pw(&user_dn, &secret)) {
00108                         DEBUG(2, ("get_credentials: Failed to lookup ldap "
00109                                   "bind creds. Using anonymous connection.\n"));
00110                         anon = True;
00111                 } else {
00112                         *dn = talloc_strdup(mem_ctx, user_dn);
00113                         SAFE_FREE( user_dn );
00114                         CHECK_ALLOC_DONE(*dn);
00115                 }
00116         }
00117 
00118         smbldap_set_creds(ldap_state, anon, *dn, secret);
00119         ret = NT_STATUS_OK;
00120 
00121 done:
00122         SAFE_FREE(secret);
00123 
00124         return ret;
00125 }
00126 
00127 
00128 /**********************************************************************
00129  Verify the sambaUnixIdPool entry in the directory.
00130 **********************************************************************/
00131 
00132 static NTSTATUS verify_idpool(void)
00133 {
00134         NTSTATUS ret;
00135         TALLOC_CTX *ctx;
00136         LDAPMessage *result = NULL;
00137         LDAPMod **mods = NULL;
00138         const char **attr_list;
00139         char *filter;
00140         int count;
00141         int rc;
00142 
00143         if ( ! idmap_alloc_ldap) {
00144                 return NT_STATUS_UNSUCCESSFUL;
00145         }
00146 
00147         ctx = talloc_new(idmap_alloc_ldap);
00148         if ( ! ctx) {
00149                 DEBUG(0, ("Out of memory!\n"));
00150                 return NT_STATUS_NO_MEMORY;
00151         }
00152 
00153         filter = talloc_asprintf(ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);
00154         CHECK_ALLOC_DONE(filter);
00155 
00156         attr_list = get_attr_list(ctx, idpool_attr_list);
00157         CHECK_ALLOC_DONE(attr_list);
00158 
00159         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
00160                                 idmap_alloc_ldap->suffix,
00161                                 LDAP_SCOPE_SUBTREE,
00162                                 filter,
00163                                 attr_list,
00164                                 0,
00165                                 &result);
00166 
00167         if (rc != LDAP_SUCCESS) {
00168                 DEBUG(1, ("Unable to verify the idpool, "
00169                           "cannot continue initialization!\n"));
00170                 return NT_STATUS_UNSUCCESSFUL;
00171         }
00172 
00173         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
00174                                    result);
00175 
00176         ldap_msgfree(result);
00177 
00178         if ( count > 1 ) {
00179                 DEBUG(0,("Multiple entries returned from %s (base == %s)\n",
00180                         filter, idmap_alloc_ldap->suffix));
00181                 ret = NT_STATUS_UNSUCCESSFUL;
00182                 goto done;
00183         }
00184         else if (count == 0) {
00185                 char *uid_str, *gid_str;
00186 
00187                 uid_str = talloc_asprintf(ctx, "%lu",
00188                                 (unsigned long)idmap_alloc_ldap->low_uid);
00189                 gid_str = talloc_asprintf(ctx, "%lu",
00190                                 (unsigned long)idmap_alloc_ldap->low_gid);
00191 
00192                 smbldap_set_mod(&mods, LDAP_MOD_ADD,
00193                                 "objectClass", LDAP_OBJ_IDPOOL);
00194                 smbldap_set_mod(&mods, LDAP_MOD_ADD,
00195                                 get_attr_key2string(idpool_attr_list,
00196                                                     LDAP_ATTR_UIDNUMBER),
00197                                 uid_str);
00198                 smbldap_set_mod(&mods, LDAP_MOD_ADD,
00199                                 get_attr_key2string(idpool_attr_list,
00200                                                     LDAP_ATTR_GIDNUMBER),
00201                                 gid_str);
00202                 if (mods) {
00203                         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state,
00204                                                 idmap_alloc_ldap->suffix,
00205                                                 mods);
00206                         ldap_mods_free(mods, True);
00207                 } else {
00208                         ret = NT_STATUS_UNSUCCESSFUL;
00209                         goto done;
00210                 }
00211         }
00212 
00213         ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL;
00214 done:
00215         talloc_free(ctx);
00216         return ret;
00217 }
00218 
00219 /*****************************************************************************
00220  Initialise idmap database.
00221 *****************************************************************************/
00222 
00223 static NTSTATUS idmap_ldap_alloc_init(const char *params)
00224 {
00225         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
00226         const char *range;
00227         const char *tmp;
00228         uid_t low_uid = 0;
00229         uid_t high_uid = 0;
00230         gid_t low_gid = 0;
00231         gid_t high_gid = 0;
00232 
00233         /* Only do init if we are online */
00234         if (idmap_is_offline()) {
00235                 return NT_STATUS_FILE_IS_OFFLINE;
00236         }
00237 
00238         idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context);
00239         CHECK_ALLOC_DONE( idmap_alloc_ldap );
00240 
00241         /* load ranges */
00242 
00243         idmap_alloc_ldap->low_uid = 0;
00244         idmap_alloc_ldap->high_uid = 0;
00245         idmap_alloc_ldap->low_gid = 0;
00246         idmap_alloc_ldap->high_gid = 0;
00247 
00248         range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
00249         if (range && range[0]) {
00250                 unsigned low_id, high_id;
00251 
00252                 if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
00253                         if (low_id < high_id) {
00254                                 idmap_alloc_ldap->low_gid = low_id;
00255                                 idmap_alloc_ldap->low_uid = low_id;
00256                                 idmap_alloc_ldap->high_gid = high_id;
00257                                 idmap_alloc_ldap->high_uid = high_id;
00258                         } else {
00259                                 DEBUG(1, ("ERROR: invalid idmap alloc range "
00260                                           "[%s]", range));
00261                         }
00262                 } else {
00263                         DEBUG(1, ("ERROR: invalid syntax for idmap alloc "
00264                                   "config:range [%s]", range));
00265                 }
00266         }
00267 
00268         if (lp_idmap_uid(&low_uid, &high_uid)) {
00269                 idmap_alloc_ldap->low_uid = low_uid;
00270                 idmap_alloc_ldap->high_uid = high_uid;
00271         }
00272 
00273         if (lp_idmap_gid(&low_gid, &high_gid)) {
00274                 idmap_alloc_ldap->low_gid = low_gid;
00275                 idmap_alloc_ldap->high_gid= high_gid;
00276         }
00277 
00278         if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) {
00279                 DEBUG(1, ("idmap uid range missing or invalid\n"));
00280                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
00281                 ret = NT_STATUS_UNSUCCESSFUL;
00282                 goto done;
00283         }
00284 
00285         if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) {
00286                 DEBUG(1, ("idmap gid range missing or invalid\n"));
00287                 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
00288                 ret = NT_STATUS_UNSUCCESSFUL;
00289                 goto done;
00290         }
00291 
00292         if (params && *params) {
00293                 /* assume location is the only parameter */
00294                 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params);
00295         } else {
00296                 tmp = lp_parm_const_string(-1, "idmap alloc config",
00297                                            "ldap_url", NULL);
00298 
00299                 if ( ! tmp) {
00300                         DEBUG(1, ("ERROR: missing idmap ldap url\n"));
00301                         ret = NT_STATUS_UNSUCCESSFUL;
00302                         goto done;
00303                 }
00304 
00305                 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp);
00306         }
00307         CHECK_ALLOC_DONE( idmap_alloc_ldap->url );
00308 
00309         tmp = lp_parm_const_string(-1, "idmap alloc config",
00310                                    "ldap_base_dn", NULL);
00311         if ( ! tmp || ! *tmp) {
00312                 tmp = lp_ldap_idmap_suffix();
00313                 if ( ! tmp) {
00314                         DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
00315                         ret = NT_STATUS_UNSUCCESSFUL;
00316                         goto done;
00317                 }
00318         }
00319 
00320         idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp);
00321         CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix );
00322 
00323         ret = smbldap_init(idmap_alloc_ldap, idmap_alloc_ldap->url,
00324                                  &idmap_alloc_ldap->smbldap_state);
00325         if (!NT_STATUS_IS_OK(ret)) {
00326                 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n",
00327                           idmap_alloc_ldap->url));
00328                 goto done;
00329         }
00330 
00331         ret = get_credentials( idmap_alloc_ldap,
00332                                idmap_alloc_ldap->smbldap_state,
00333                                "idmap alloc config", NULL,
00334                                &idmap_alloc_ldap->user_dn );
00335         if ( !NT_STATUS_IS_OK(ret) ) {
00336                 DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection "
00337                          "credentials (%s)\n", nt_errstr(ret)));
00338                 goto done;
00339         }
00340 
00341         /* see if the idmap suffix and sub entries exists */
00342 
00343         ret = verify_idpool();
00344 
00345  done:
00346         if ( !NT_STATUS_IS_OK( ret ) )
00347                 TALLOC_FREE( idmap_alloc_ldap );
00348 
00349         return ret;
00350 }
00351 
00352 /********************************
00353  Allocate a new uid or gid
00354 ********************************/
00355 
00356 static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid)
00357 {
00358         TALLOC_CTX *ctx;
00359         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
00360         int rc = LDAP_SERVER_DOWN;
00361         int count = 0;
00362         LDAPMessage *result = NULL;
00363         LDAPMessage *entry = NULL;
00364         LDAPMod **mods = NULL;
00365         char *id_str;
00366         char *new_id_str;
00367         char *filter = NULL;
00368         const char *dn = NULL;
00369         const char **attr_list;
00370         const char *type;
00371 
00372         /* Only do query if we are online */
00373         if (idmap_is_offline()) {
00374                 return NT_STATUS_FILE_IS_OFFLINE;
00375         }
00376 
00377         if ( ! idmap_alloc_ldap) {
00378                 return NT_STATUS_UNSUCCESSFUL;
00379         }
00380 
00381         ctx = talloc_new(idmap_alloc_ldap);
00382         if ( ! ctx) {
00383                 DEBUG(0, ("Out of memory!\n"));
00384                 return NT_STATUS_NO_MEMORY;
00385         }
00386 
00387         /* get type */
00388         switch (xid->type) {
00389 
00390         case ID_TYPE_UID:
00391                 type = get_attr_key2string(idpool_attr_list,
00392                                            LDAP_ATTR_UIDNUMBER);
00393                 break;
00394 
00395         case ID_TYPE_GID:
00396                 type = get_attr_key2string(idpool_attr_list,
00397                                            LDAP_ATTR_GIDNUMBER);
00398                 break;
00399 
00400         default:
00401                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
00402                 return NT_STATUS_INVALID_PARAMETER;
00403         }
00404 
00405         filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
00406         CHECK_ALLOC_DONE(filter);
00407 
00408         attr_list = get_attr_list(ctx, idpool_attr_list);
00409         CHECK_ALLOC_DONE(attr_list);
00410 
00411         DEBUG(10, ("Search of the id pool (filter: %s)\n", filter));
00412 
00413         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
00414                                 idmap_alloc_ldap->suffix,
00415                                LDAP_SCOPE_SUBTREE, filter,
00416                                attr_list, 0, &result);
00417 
00418         if (rc != LDAP_SUCCESS) {
00419                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
00420                 goto done;
00421         }
00422 
00423         talloc_autofree_ldapmsg(ctx, result);
00424 
00425         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
00426                                    result);
00427         if (count != 1) {
00428                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
00429                 goto done;
00430         }
00431 
00432         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
00433                                  result);
00434 
00435         dn = smbldap_talloc_dn(ctx,
00436                                idmap_alloc_ldap->smbldap_state->ldap_struct,
00437                                entry);
00438         if ( ! dn) {
00439                 goto done;
00440         }
00441 
00442         if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
00443                                 entry, type, ctx))) {
00444                 DEBUG(0,("%s attribute not found\n", type));
00445                 goto done;
00446         }
00447         if ( ! id_str) {
00448                 DEBUG(0,("Out of memory\n"));
00449                 ret = NT_STATUS_NO_MEMORY;
00450                 goto done;
00451         }
00452 
00453         xid->id = strtoul(id_str, NULL, 10);
00454 
00455         /* make sure we still have room to grow */
00456 
00457         switch (xid->type) {
00458         case ID_TYPE_UID:
00459                 if (xid->id > idmap_alloc_ldap->high_uid) {
00460                         DEBUG(0,("Cannot allocate uid above %lu!\n",
00461                                  (unsigned long)idmap_alloc_ldap->high_uid));
00462                         goto done;
00463                 }
00464                 break;
00465 
00466         case ID_TYPE_GID:
00467                 if (xid->id > idmap_alloc_ldap->high_gid) {
00468                         DEBUG(0,("Cannot allocate gid above %lu!\n",
00469                                  (unsigned long)idmap_alloc_ldap->high_uid));
00470                         goto done;
00471                 }
00472                 break;
00473 
00474         default:
00475                 /* impossible */
00476                 goto done;
00477         }
00478 
00479         new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id + 1);
00480         if ( ! new_id_str) {
00481                 DEBUG(0,("Out of memory\n"));
00482                 ret = NT_STATUS_NO_MEMORY;
00483                 goto done;
00484         }
00485 
00486         smbldap_set_mod(&mods, LDAP_MOD_DELETE, type, id_str);
00487         smbldap_set_mod(&mods, LDAP_MOD_ADD, type, new_id_str);
00488 
00489         if (mods == NULL) {
00490                 DEBUG(0,("smbldap_set_mod() failed.\n"));
00491                 goto done;
00492         }
00493 
00494         DEBUG(10, ("Try to atomically increment the id (%s -> %s)\n",
00495                    id_str, new_id_str));
00496 
00497         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
00498 
00499         ldap_mods_free(mods, True);
00500 
00501         if (rc != LDAP_SUCCESS) {
00502                 DEBUG(1,("Failed to allocate new %s. "
00503                          "smbldap_modify() failed.\n", type));
00504                 goto done;
00505         }
00506 
00507         ret = NT_STATUS_OK;
00508 
00509 done:
00510         talloc_free(ctx);
00511         return ret;
00512 }
00513 
00514 /**********************************
00515  Get current highest id.
00516 **********************************/
00517 
00518 static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid)
00519 {
00520         TALLOC_CTX *memctx;
00521         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
00522         int rc = LDAP_SERVER_DOWN;
00523         int count = 0;
00524         LDAPMessage *result = NULL;
00525         LDAPMessage *entry = NULL;
00526         char *id_str;
00527         char *filter = NULL;
00528         const char **attr_list;
00529         const char *type;
00530 
00531         /* Only do query if we are online */
00532         if (idmap_is_offline()) {
00533                 return NT_STATUS_FILE_IS_OFFLINE;
00534         }
00535 
00536         if ( ! idmap_alloc_ldap) {
00537                 return NT_STATUS_UNSUCCESSFUL;
00538         }
00539 
00540         memctx = talloc_new(idmap_alloc_ldap);
00541         if ( ! memctx) {
00542                 DEBUG(0, ("Out of memory!\n"));
00543                 return NT_STATUS_NO_MEMORY;
00544         }
00545 
00546         /* get type */
00547         switch (xid->type) {
00548 
00549         case ID_TYPE_UID:
00550                 type = get_attr_key2string(idpool_attr_list,
00551                                            LDAP_ATTR_UIDNUMBER);
00552                 break;
00553 
00554         case ID_TYPE_GID:
00555                 type = get_attr_key2string(idpool_attr_list,
00556                                            LDAP_ATTR_GIDNUMBER);
00557                 break;
00558 
00559         default:
00560                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
00561                 return NT_STATUS_INVALID_PARAMETER;
00562         }
00563 
00564         filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
00565         CHECK_ALLOC_DONE(filter);
00566 
00567         attr_list = get_attr_list(memctx, idpool_attr_list);
00568         CHECK_ALLOC_DONE(attr_list);
00569 
00570         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
00571                                 idmap_alloc_ldap->suffix,
00572                                LDAP_SCOPE_SUBTREE, filter,
00573                                attr_list, 0, &result);
00574 
00575         if (rc != LDAP_SUCCESS) {
00576                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
00577                 goto done;
00578         }
00579 
00580         talloc_autofree_ldapmsg(memctx, result);
00581 
00582         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
00583                                    result);
00584         if (count != 1) {
00585                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
00586                 goto done;
00587         }
00588 
00589         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
00590                                  result);
00591 
00592         id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct,
00593                         entry, type, memctx);
00594         if ( ! id_str) {
00595                 DEBUG(0,("%s attribute not found\n", type));
00596                 goto done;
00597         }
00598         if ( ! id_str) {
00599                 DEBUG(0,("Out of memory\n"));
00600                 ret = NT_STATUS_NO_MEMORY;
00601                 goto done;
00602         }
00603 
00604         xid->id = strtoul(id_str, NULL, 10);
00605 
00606         ret = NT_STATUS_OK;
00607 done:
00608         talloc_free(memctx);
00609         return ret;
00610 }
00611 /**********************************
00612  Set highest id.
00613 **********************************/
00614 
00615 static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)
00616 {
00617         TALLOC_CTX *ctx;
00618         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
00619         int rc = LDAP_SERVER_DOWN;
00620         int count = 0;
00621         LDAPMessage *result = NULL;
00622         LDAPMessage *entry = NULL;
00623         LDAPMod **mods = NULL;
00624         char *new_id_str;
00625         char *filter = NULL;
00626         const char *dn = NULL;
00627         const char **attr_list;
00628         const char *type;
00629 
00630         /* Only do query if we are online */
00631         if (idmap_is_offline()) {
00632                 return NT_STATUS_FILE_IS_OFFLINE;
00633         }
00634 
00635         if ( ! idmap_alloc_ldap) {
00636                 return NT_STATUS_UNSUCCESSFUL;
00637         }
00638 
00639         ctx = talloc_new(idmap_alloc_ldap);
00640         if ( ! ctx) {
00641                 DEBUG(0, ("Out of memory!\n"));
00642                 return NT_STATUS_NO_MEMORY;
00643         }
00644 
00645         /* get type */
00646         switch (xid->type) {
00647 
00648         case ID_TYPE_UID:
00649                 type = get_attr_key2string(idpool_attr_list,
00650                                            LDAP_ATTR_UIDNUMBER);
00651                 break;
00652 
00653         case ID_TYPE_GID:
00654                 type = get_attr_key2string(idpool_attr_list,
00655                                            LDAP_ATTR_GIDNUMBER);
00656                 break;
00657 
00658         default:
00659                 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
00660                 return NT_STATUS_INVALID_PARAMETER;
00661         }
00662 
00663         filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
00664         CHECK_ALLOC_DONE(filter);
00665 
00666         attr_list = get_attr_list(ctx, idpool_attr_list);
00667         CHECK_ALLOC_DONE(attr_list);
00668 
00669         rc = smbldap_search(idmap_alloc_ldap->smbldap_state,
00670                                 idmap_alloc_ldap->suffix,
00671                                LDAP_SCOPE_SUBTREE, filter,
00672                                attr_list, 0, &result);
00673 
00674         if (rc != LDAP_SUCCESS) {
00675                 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));
00676                 goto done;
00677         }
00678 
00679         talloc_autofree_ldapmsg(ctx, result);
00680 
00681         count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,
00682                                    result);
00683         if (count != 1) {
00684                 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));
00685                 goto done;
00686         }
00687 
00688         entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,
00689                                  result);
00690 
00691         dn = smbldap_talloc_dn(ctx,
00692                                 idmap_alloc_ldap->smbldap_state->ldap_struct,
00693                                 entry);
00694         if ( ! dn) {
00695                 goto done;
00696         }
00697 
00698         new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);
00699         if ( ! new_id_str) {
00700                 DEBUG(0,("Out of memory\n"));
00701                 ret = NT_STATUS_NO_MEMORY;
00702                 goto done;
00703         }
00704 
00705         smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);
00706 
00707         if (mods == NULL) {
00708                 DEBUG(0,("smbldap_set_mod() failed.\n"));
00709                 goto done;
00710         }
00711 
00712         rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);
00713 
00714         ldap_mods_free(mods, True);
00715 
00716         if (rc != LDAP_SUCCESS) {
00717                 DEBUG(1,("Failed to allocate new %s. "
00718                          "smbldap_modify() failed.\n", type));
00719                 goto done;
00720         }
00721 
00722         ret = NT_STATUS_OK;
00723 
00724 done:
00725         talloc_free(ctx);
00726         return ret;
00727 }
00728 
00729 /**********************************
00730  Close idmap ldap alloc
00731 **********************************/
00732 
00733 static NTSTATUS idmap_ldap_alloc_close(void)
00734 {
00735         if (idmap_alloc_ldap) {
00736                 smbldap_free_struct(&idmap_alloc_ldap->smbldap_state);
00737                 DEBUG(5,("The connection to the LDAP server was closed\n"));
00738                 /* maybe free the results here --metze */
00739                 TALLOC_FREE(idmap_alloc_ldap);
00740         }
00741         return NT_STATUS_OK;
00742 }
00743 
00744 
00745 /**********************************************************************
00746  IDMAP MAPPING LDAP BACKEND
00747 **********************************************************************/
00748 
00749 static int idmap_ldap_close_destructor(struct idmap_ldap_context *ctx)
00750 {
00751         smbldap_free_struct(&ctx->smbldap_state);
00752         DEBUG(5,("The connection to the LDAP server was closed\n"));
00753         /* maybe free the results here --metze */
00754 
00755         return 0;
00756 }
00757 
00758 /********************************
00759  Initialise idmap database.
00760 ********************************/
00761 
00762 static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
00763 {
00764         NTSTATUS ret;
00765         struct idmap_ldap_context *ctx = NULL;
00766         char *config_option = NULL;
00767         const char *range = NULL;
00768         const char *tmp = NULL;
00769 
00770         /* Only do init if we are online */
00771         if (idmap_is_offline()) {
00772                 return NT_STATUS_FILE_IS_OFFLINE;
00773         }
00774 
00775         ctx = TALLOC_ZERO_P(dom, struct idmap_ldap_context);
00776         if ( ! ctx) {
00777                 DEBUG(0, ("Out of memory!\n"));
00778                 return NT_STATUS_NO_MEMORY;
00779         }
00780 
00781         config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
00782         if ( ! config_option) {
00783                 DEBUG(0, ("Out of memory!\n"));
00784                 ret = NT_STATUS_NO_MEMORY;
00785                 goto done;
00786         }
00787 
00788         /* load ranges */
00789         range = lp_parm_const_string(-1, config_option, "range", NULL);
00790         if (range && range[0]) {
00791                 if ((sscanf(range, "%u - %u", &ctx->filter_low_id,
00792                                                 &ctx->filter_high_id) != 2) ||
00793                     (ctx->filter_low_id > ctx->filter_high_id)) {
00794                         DEBUG(1, ("ERROR: invalid filter range [%s]", range));
00795                         ctx->filter_low_id = 0;
00796                         ctx->filter_high_id = 0;
00797                 }
00798         }
00799 
00800         if (dom->params && *(dom->params)) {
00801                 /* assume location is the only parameter */
00802                 ctx->url = talloc_strdup(ctx, dom->params);
00803         } else {
00804                 tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
00805 
00806                 if ( ! tmp) {
00807                         DEBUG(1, ("ERROR: missing idmap ldap url\n"));
00808                         ret = NT_STATUS_UNSUCCESSFUL;
00809                         goto done;
00810                 }
00811 
00812                 ctx->url = talloc_strdup(ctx, tmp);
00813         }
00814         CHECK_ALLOC_DONE(ctx->url);
00815 
00816         tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL);
00817         if ( ! tmp || ! *tmp) {
00818                 tmp = lp_ldap_idmap_suffix();
00819                 if ( ! tmp) {
00820                         DEBUG(1, ("ERROR: missing idmap ldap suffix\n"));
00821                         ret = NT_STATUS_UNSUCCESSFUL;
00822                         goto done;
00823                 }
00824         }
00825 
00826         ctx->suffix = talloc_strdup(ctx, tmp);
00827         CHECK_ALLOC_DONE(ctx->suffix);
00828 
00829         ret = smbldap_init(ctx, ctx->url, &ctx->smbldap_state);
00830         if (!NT_STATUS_IS_OK(ret)) {
00831                 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url));
00832                 goto done;
00833         }
00834 
00835         ret = get_credentials( ctx, ctx->smbldap_state, config_option,
00836                                dom, &ctx->user_dn );
00837         if ( !NT_STATUS_IS_OK(ret) ) {
00838                 DEBUG(1,("idmap_ldap_db_init: Failed to get connection "
00839                          "credentials (%s)\n", nt_errstr(ret)));
00840                 goto done;
00841         }
00842 
00843         /* set the destructor on the context, so that resource are properly
00844            freed if the contexts is released */
00845 
00846         talloc_set_destructor(ctx, idmap_ldap_close_destructor);
00847 
00848         dom->private_data = ctx;
00849         dom->initialized = True;
00850 
00851         talloc_free(config_option);
00852         return NT_STATUS_OK;
00853 
00854 /*failed */
00855 done:
00856         talloc_free(ctx);
00857         return ret;
00858 }
00859 
00860 /* max number of ids requested per batch query */
00861 #define IDMAP_LDAP_MAX_IDS 30
00862 
00863 /**********************************
00864  lookup a set of unix ids.
00865 **********************************/
00866 
00867 /* this function searches up to IDMAP_LDAP_MAX_IDS entries
00868  * in maps for a match */
00869 static struct id_map *find_map_by_id(struct id_map **maps,
00870                                      enum id_type type,
00871                                      uint32_t id)
00872 {
00873         int i;
00874 
00875         for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
00876                 if (maps[i] == NULL) { /* end of the run */
00877                         return NULL;
00878                 }
00879                 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {
00880                         return maps[i];
00881                 }
00882         }
00883 
00884         return NULL;
00885 }
00886 
00887 static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
00888                                            struct id_map **ids)
00889 {
00890         NTSTATUS ret;
00891         TALLOC_CTX *memctx;
00892         struct idmap_ldap_context *ctx;
00893         LDAPMessage *result = NULL;
00894         const char *uidNumber;
00895         const char *gidNumber;
00896         const char **attr_list;
00897         char *filter = NULL;
00898         BOOL multi = False;
00899         int idx = 0;
00900         int bidx = 0;
00901         int count;
00902         int rc;
00903         int i;
00904 
00905         /* Only do query if we are online */
00906         if (idmap_is_offline()) {
00907                 return NT_STATUS_FILE_IS_OFFLINE;
00908         }
00909 
00910         /* Initilization my have been deferred because we were offline */
00911         if ( ! dom->initialized) {
00912                 ret = idmap_ldap_db_init(dom);
00913                 if ( ! NT_STATUS_IS_OK(ret)) {
00914                         return ret;
00915                 }
00916         }
00917 
00918         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
00919 
00920         memctx = talloc_new(ctx);
00921         if ( ! memctx) {
00922                 DEBUG(0, ("Out of memory!\n"));
00923                 return NT_STATUS_NO_MEMORY;
00924         }
00925 
00926         uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
00927         gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
00928 
00929         attr_list = get_attr_list(memctx, sidmap_attr_list);
00930 
00931         if ( ! ids[1]) {
00932                 /* if we are requested just one mapping use the simple filter */
00933 
00934                 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%lu))",
00935                                 LDAP_OBJ_IDMAP_ENTRY,
00936                                 (ids[0]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
00937                                 (unsigned long)ids[0]->xid.id);
00938                 CHECK_ALLOC_DONE(filter);
00939                 DEBUG(10, ("Filter: [%s]\n", filter));
00940         } else {
00941                 /* multiple mappings */
00942                 multi = True;
00943         }
00944 
00945 again:
00946         if (multi) {
00947 
00948                 talloc_free(filter);
00949                 filter = talloc_asprintf(memctx,
00950                                          "(&(objectClass=%s)(|",
00951                                          LDAP_OBJ_IDMAP_ENTRY);
00952                 CHECK_ALLOC_DONE(filter);
00953 
00954                 bidx = idx;
00955                 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
00956                         filter = talloc_asprintf_append(filter, "(%s=%lu)",
00957                                         (ids[idx]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
00958                                         (unsigned long)ids[idx]->xid.id);
00959                         CHECK_ALLOC_DONE(filter);
00960                 }
00961                 filter = talloc_asprintf_append(filter, "))");
00962                 CHECK_ALLOC_DONE(filter);
00963                 DEBUG(10, ("Filter: [%s]\n", filter));
00964         } else {
00965                 bidx = 0;
00966                 idx = 1;
00967         }
00968 
00969         rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
00970                 filter, attr_list, 0, &result);
00971 
00972         if (rc != LDAP_SUCCESS) {
00973                 DEBUG(3,("Failure looking up ids (%s)\n", ldap_err2string(rc)));
00974                 ret = NT_STATUS_UNSUCCESSFUL;
00975                 goto done;
00976         }
00977 
00978         count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
00979 
00980         if (count == 0) {
00981                 DEBUG(10, ("NO SIDs found\n"));
00982         }
00983 
00984         for (i = 0; i < count; i++) {
00985                 LDAPMessage *entry = NULL;
00986                 char *sidstr = NULL;
00987                 char *tmp = NULL;
00988                 enum id_type type;
00989                 struct id_map *map;
00990                 uint32_t id;
00991 
00992                 if (i == 0) { /* first entry */
00993                         entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
00994                                                  result);
00995                 } else { /* following ones */
00996                         entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
00997                                                 entry);
00998                 }
00999                 if ( ! entry) {
01000                         DEBUG(2, ("ERROR: Unable to fetch ldap entries "
01001                                   "from results\n"));
01002                         break;
01003                 }
01004 
01005                 /* first check if the SID is present */
01006                 sidstr = smbldap_talloc_single_attribute(
01007                                 ctx->smbldap_state->ldap_struct,
01008                                 entry, LDAP_ATTRIBUTE_SID, memctx);
01009                 if ( ! sidstr) { /* no sid, skip entry */
01010                         DEBUG(2, ("WARNING SID not found on entry\n"));
01011                         continue;
01012                 }
01013 
01014                 /* now try to see if it is a uid, if not try with a gid
01015                  * (gid is more common, but in case both uidNumber and
01016                  * gidNumber are returned the SID is mapped to the uid
01017                  *not the gid) */
01018                 type = ID_TYPE_UID;
01019                 tmp = smbldap_talloc_single_attribute(
01020                                 ctx->smbldap_state->ldap_struct,
01021                                 entry, uidNumber, memctx);
01022                 if ( ! tmp) {
01023                         type = ID_TYPE_GID;
01024                         tmp = smbldap_talloc_single_attribute(
01025                                         ctx->smbldap_state->ldap_struct,
01026                                         entry, gidNumber, memctx);
01027                 }
01028                 if ( ! tmp) { /* wow very strange entry, how did it match ? */
01029                         DEBUG(5, ("Unprobable match on (%s), no uidNumber, "
01030                                   "nor gidNumber returned\n", sidstr));
01031                         TALLOC_FREE(sidstr);
01032                         continue;
01033                 }
01034 
01035                 id = strtoul(tmp, NULL, 10);
01036                 if ((id == 0) ||
01037                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
01038                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
01039                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
01040                                   "Filtered!\n", id,
01041                                   ctx->filter_low_id, ctx->filter_high_id));
01042                         TALLOC_FREE(sidstr);
01043                         TALLOC_FREE(tmp);
01044                         continue;
01045                 }
01046                 TALLOC_FREE(tmp);
01047 
01048                 map = find_map_by_id(&ids[bidx], type, id);
01049                 if (!map) {
01050                         DEBUG(2, ("WARNING: couldn't match sid (%s) "
01051                                   "with requested ids\n", sidstr));
01052                         TALLOC_FREE(sidstr);
01053                         continue;
01054                 }
01055 
01056                 if ( ! string_to_sid(map->sid, sidstr)) {
01057                         DEBUG(2, ("ERROR: Invalid SID on entry\n"));
01058                         TALLOC_FREE(sidstr);
01059                         continue;
01060                 }
01061                 TALLOC_FREE(sidstr);
01062 
01063                 /* mapped */
01064                 map->status = ID_MAPPED;
01065 
01066                 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
01067                            sid_string_static(map->sid),
01068                            (unsigned long)map->xid.id, map->xid.type));
01069         }
01070 
01071         /* free the ldap results */
01072         if (result) {
01073                 ldap_msgfree(result);
01074                 result = NULL;
01075         }
01076 
01077         if (multi && ids[idx]) { /* still some values to map */
01078                 goto again;
01079         }
01080 
01081         ret = NT_STATUS_OK;
01082 
01083         /* mark all unknwon/expired ones as unmapped */
01084         for (i = 0; ids[i]; i++) {
01085                 if (ids[i]->status != ID_MAPPED)
01086                         ids[i]->status = ID_UNMAPPED;
01087         }
01088 
01089 done:
01090         talloc_free(memctx);
01091         return ret;
01092 }
01093 
01094 /**********************************
01095  lookup a set of sids.
01096 **********************************/
01097 
01098 /* this function searches up to IDMAP_LDAP_MAX_IDS entries
01099  * in maps for a match */
01100 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID *sid)
01101 {
01102         int i;
01103 
01104         for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {
01105                 if (maps[i] == NULL) { /* end of the run */
01106                         return NULL;
01107                 }
01108                 if (sid_equal(maps[i]->sid, sid)) {
01109                         return maps[i];
01110                 }
01111         }
01112 
01113         return NULL;
01114 }
01115 
01116 static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
01117                                            struct id_map **ids)
01118 {
01119         LDAPMessage *entry = NULL;
01120         NTSTATUS ret;
01121         TALLOC_CTX *memctx;
01122         struct idmap_ldap_context *ctx;
01123         LDAPMessage *result = NULL;
01124         const char *uidNumber;
01125         const char *gidNumber;
01126         const char **attr_list;
01127         char *filter = NULL;
01128         BOOL multi = False;
01129         int idx = 0;
01130         int bidx = 0;
01131         int count;
01132         int rc;
01133         int i;
01134 
01135         /* Only do query if we are online */
01136         if (idmap_is_offline()) {
01137                 return NT_STATUS_FILE_IS_OFFLINE;
01138         }
01139 
01140         /* Initilization my have been deferred because we were offline */
01141         if ( ! dom->initialized) {
01142                 ret = idmap_ldap_db_init(dom);
01143                 if ( ! NT_STATUS_IS_OK(ret)) {
01144                         return ret;
01145                 }
01146         }
01147 
01148         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
01149 
01150         memctx = talloc_new(ctx);
01151         if ( ! memctx) {
01152                 DEBUG(0, ("Out of memory!\n"));
01153                 return NT_STATUS_NO_MEMORY;
01154         }
01155 
01156         uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
01157         gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);
01158 
01159         attr_list = get_attr_list(memctx, sidmap_attr_list);
01160 
01161         if ( ! ids[1]) {
01162                 /* if we are requested just one mapping use the simple filter */
01163 
01164                 filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))",
01165                                 LDAP_OBJ_IDMAP_ENTRY,
01166                                 LDAP_ATTRIBUTE_SID,
01167                                 sid_string_static(ids[0]->sid));
01168                 CHECK_ALLOC_DONE(filter);
01169                 DEBUG(10, ("Filter: [%s]\n", filter));
01170         } else {
01171                 /* multiple mappings */
01172                 multi = True;
01173         }
01174 
01175 again:
01176         if (multi) {
01177 
01178                 TALLOC_FREE(filter);
01179                 filter = talloc_asprintf(memctx,
01180                                          "(&(objectClass=%s)(|",
01181                                          LDAP_OBJ_IDMAP_ENTRY);
01182                 CHECK_ALLOC_DONE(filter);
01183 
01184                 bidx = idx;
01185                 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
01186                         filter = talloc_asprintf_append(filter, "(%s=%s)",
01187                                         LDAP_ATTRIBUTE_SID,
01188                                         sid_string_static(ids[idx]->sid));
01189                         CHECK_ALLOC_DONE(filter);
01190                 }
01191                 filter = talloc_asprintf_append(filter, "))");
01192                 CHECK_ALLOC_DONE(filter);
01193                 DEBUG(10, ("Filter: [%s]", filter));
01194         } else {
01195                 bidx = 0;
01196                 idx = 1;
01197         }
01198 
01199         rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
01200                 filter, attr_list, 0, &result);
01201 
01202         if (rc != LDAP_SUCCESS) {
01203                 DEBUG(3,("Failure looking up sids (%s)\n",
01204                          ldap_err2string(rc)));
01205                 ret = NT_STATUS_UNSUCCESSFUL;
01206                 goto done;
01207         }
01208 
01209         count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);
01210 
01211         if (count == 0) {
01212                 DEBUG(10, ("NO SIDs found\n"));
01213         }
01214 
01215         for (i = 0; i < count; i++) {
01216                 char *sidstr = NULL;
01217                 char *tmp = NULL;
01218                 enum id_type type;
01219                 struct id_map *map;
01220                 DOM_SID sid;
01221                 uint32_t id;
01222 
01223                 if (i == 0) { /* first entry */
01224                         entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
01225                                                  result);
01226                 } else { /* following ones */
01227                         entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
01228                                                 entry);
01229                 }
01230                 if ( ! entry) {
01231                         DEBUG(2, ("ERROR: Unable to fetch ldap entries "
01232                                   "from results\n"));
01233                         break;
01234                 }
01235 
01236                 /* first check if the SID is present */
01237                 sidstr = smbldap_talloc_single_attribute(
01238                                 ctx->smbldap_state->ldap_struct,
01239                                 entry, LDAP_ATTRIBUTE_SID, memctx);
01240                 if ( ! sidstr) { /* no sid ??, skip entry */
01241                         DEBUG(2, ("WARNING SID not found on entry\n"));
01242                         continue;
01243                 }
01244 
01245                 if ( ! string_to_sid(&sid, sidstr)) {
01246                         DEBUG(2, ("ERROR: Invalid SID on entry\n"));
01247                         TALLOC_FREE(sidstr);
01248                         continue;
01249                 }
01250 
01251                 map = find_map_by_sid(&ids[bidx], &sid);
01252                 if (!map) {
01253                         DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
01254                                   "in ids", sidstr));
01255                         TALLOC_FREE(sidstr);
01256                         continue;
01257                 }
01258 
01259                 TALLOC_FREE(sidstr);
01260 
01261                 /* now try to see if it is a uid, if not try with a gid
01262                  * (gid is more common, but in case both uidNumber and
01263                  * gidNumber are returned the SID is mapped to the uid
01264                  * not the gid) */
01265                 type = ID_TYPE_UID;
01266                 tmp = smbldap_talloc_single_attribute(
01267                                 ctx->smbldap_state->ldap_struct,
01268                                 entry, uidNumber, memctx);
01269                 if ( ! tmp) {
01270                         type = ID_TYPE_GID;
01271                         tmp = smbldap_talloc_single_attribute(
01272                                         ctx->smbldap_state->ldap_struct,
01273                                         entry, gidNumber, memctx);
01274                 }
01275                 if ( ! tmp) { /* no ids ?? */
01276                         DEBUG(5, ("no uidNumber, "
01277                                   "nor gidNumber attributes found\n"));
01278                         continue;
01279                 }
01280 
01281                 id = strtoul(tmp, NULL, 10);
01282                 if ((id == 0) ||
01283                     (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
01284                     (ctx->filter_high_id && (id > ctx->filter_high_id))) {
01285                         DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
01286                                   "Filtered!\n", id,
01287                                   ctx->filter_low_id, ctx->filter_high_id));
01288                         TALLOC_FREE(tmp);
01289                         continue;
01290                 }
01291                 TALLOC_FREE(tmp);
01292 
01293                 /* mapped */
01294                 map->xid.type = type;
01295                 map->xid.id = id;
01296                 map->status = ID_MAPPED;
01297 
01298                 DEBUG(10, ("Mapped %s -> %lu (%d)\n",
01299                            sid_string_static(map->sid),
01300                            (unsigned long)map->xid.id, map->xid.type));
01301         }
01302 
01303         /* free the ldap results */
01304         if (result) {
01305                 ldap_msgfree(result);
01306                 result = NULL;
01307         }
01308 
01309         if (multi && ids[idx]) { /* still some values to map */
01310                 goto again;
01311         }
01312 
01313         ret = NT_STATUS_OK;
01314 
01315         /* mark all unknwon/expired ones as unmapped */
01316         for (i = 0; ids[i]; i++) {
01317                 if (ids[i]->status != ID_MAPPED)
01318                         ids[i]->status = ID_UNMAPPED;
01319         }
01320 
01321 done:
01322         talloc_free(memctx);
01323         return ret;
01324 }
01325 
01326 /**********************************
01327  set a mapping.
01328 **********************************/
01329 
01330 /* TODO: change this:  This function cannot be called to modify a mapping,
01331  * only set a new one */
01332 
01333 static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
01334                                        const struct id_map *map)
01335 {
01336         NTSTATUS ret;
01337         TALLOC_CTX *memctx;
01338         struct idmap_ldap_context *ctx;
01339         LDAPMessage *entry = NULL;
01340         LDAPMod **mods = NULL;
01341         const char *type;
01342         char *id_str;
01343         char *sid;
01344         char *dn;
01345         int rc = -1;
01346 
01347         /* Only do query if we are online */
01348         if (idmap_is_offline()) {
01349                 return NT_STATUS_FILE_IS_OFFLINE;
01350         }
01351 
01352         /* Initilization my have been deferred because we were offline */
01353         if ( ! dom->initialized) {
01354                 ret = idmap_ldap_db_init(dom);
01355                 if ( ! NT_STATUS_IS_OK(ret)) {
01356                         return ret;
01357                 }
01358         }
01359 
01360         ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
01361 
01362         switch(map->xid.type) {
01363         case ID_TYPE_UID:
01364                 type = get_attr_key2string(sidmap_attr_list,
01365                                            LDAP_ATTR_UIDNUMBER);
01366                 break;
01367 
01368         case ID_TYPE_GID:
01369                 type = get_attr_key2string(sidmap_attr_list,
01370                                            LDAP_ATTR_GIDNUMBER);
01371                 break;
01372 
01373         default:
01374                 return NT_STATUS_INVALID_PARAMETER;
01375         }
01376 
01377         memctx = talloc_new(ctx);
01378         if ( ! memctx) {
01379                 DEBUG(0, ("Out of memory!\n"));
01380                 return NT_STATUS_NO_MEMORY;
01381         }
01382 
01383         id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
01384         CHECK_ALLOC_DONE(id_str);
01385 
01386         sid = talloc_strdup(memctx, sid_string_static(map->sid));
01387         CHECK_ALLOC_DONE(sid);
01388 
01389         dn = talloc_asprintf(memctx, "%s=%s,%s",
01390                         get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
01391                         sid,
01392                         ctx->suffix);
01393         CHECK_ALLOC_DONE(dn);
01394 
01395         smbldap_set_mod(&mods, LDAP_MOD_ADD,
01396                         "objectClass", LDAP_OBJ_IDMAP_ENTRY);
01397 
01398         smbldap_make_mod(ctx->smbldap_state->ldap_struct,
01399                          entry, &mods, type, id_str);
01400 
01401         smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
01402                          get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
01403                          sid);
01404 
01405         if ( ! mods) {
01406                 DEBUG(2, ("ERROR: No mods?\n"));
01407                 ret = NT_STATUS_UNSUCCESSFUL;
01408                 goto done;
01409         }
01410 
01411         /* TODO: remove conflicting mappings! */
01412 
01413         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);
01414 
01415         DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));
01416 
01417         rc = smbldap_add(ctx->smbldap_state, dn, mods);
01418         ldap_mods_free(mods, True);
01419 
01420         if (rc != LDAP_SUCCESS) {
01421                 char *ld_error = NULL;
01422                 ldap_get_option(ctx->smbldap_state->ldap_struct,
01423                                 LDAP_OPT_ERROR_STRING, &ld_error);
01424                 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
01425                          "mapping [%s]\n", sid,
01426                          (unsigned long)map->xid.id, type));
01427                 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
01428                         ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
01429                 if (ld_error) {
01430                         ldap_memfree(ld_error);
01431                 }
01432                 ret = NT_STATUS_UNSUCCESSFUL;
01433                 goto done;
01434         }
01435 
01436         DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
01437                   "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));
01438 
01439         ret = NT_STATUS_OK;
01440 
01441 done:
01442         talloc_free(memctx);
01443         return ret;
01444 }
01445 
01446 /**********************************
01447  Close the idmap ldap instance
01448 **********************************/
01449 
01450 static NTSTATUS idmap_ldap_close(struct idmap_domain *dom)
01451 {
01452         struct idmap_ldap_context *ctx;
01453 
01454         if (dom->private_data) {
01455                 ctx = talloc_get_type(dom->private_data,
01456                                       struct idmap_ldap_context);
01457 
01458                 talloc_free(ctx);
01459                 dom->private_data = NULL;
01460         }
01461 
01462         return NT_STATUS_OK;
01463 }
01464 
01465 static struct idmap_methods idmap_ldap_methods = {
01466 
01467         .init = idmap_ldap_db_init,
01468         .unixids_to_sids = idmap_ldap_unixids_to_sids,
01469         .sids_to_unixids = idmap_ldap_sids_to_unixids,
01470         .set_mapping = idmap_ldap_set_mapping,
01471         .close_fn = idmap_ldap_close
01472 };
01473 
01474 static struct idmap_alloc_methods idmap_ldap_alloc_methods = {
01475 
01476         .init = idmap_ldap_alloc_init,
01477         .allocate_id = idmap_ldap_allocate_id,
01478         .get_id_hwm = idmap_ldap_get_hwm,
01479         .set_id_hwm = idmap_ldap_set_hwm,
01480         .close_fn = idmap_ldap_alloc_close,
01481         /* .dump_data = TODO */
01482 };
01483 
01484 NTSTATUS idmap_alloc_ldap_init(void)
01485 {
01486         return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",
01487                                         &idmap_ldap_alloc_methods);
01488 }
01489 
01490 NTSTATUS idmap_ldap_init(void)
01491 {
01492         NTSTATUS ret;
01493 
01494         /* FIXME: bad hack to actually register also the alloc_ldap module
01495          * without changining configure.in */
01496         ret = idmap_alloc_ldap_init();
01497         if (! NT_STATUS_IS_OK(ret)) {
01498                 return ret;
01499         }
01500         return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
01501                                   &idmap_ldap_methods);
01502 }
01503 

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