root/source3/winbindd/idmap_adex/idmap_adex.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _idmap_adex_init
  2. _idmap_adex_get_sid_from_id
  3. _idmap_adex_get_id_from_sid
  4. _idmap_adex_set_mapping
  5. _idmap_adex_remove_mapping
  6. _idmap_adex_dump
  7. _idmap_adex_close
  8. _nss_adex_init
  9. _nss_adex_get_info
  10. _nss_adex_map_to_alias
  11. _nss_adex_map_from_alias
  12. _nss_adex_close
  13. idmap_adex_init
  14. nss_info_adex_init

   1 /*
   2  * idmap_adex: Support for D Forests
   3  *
   4  * Copyright (C) Gerald (Jerry) Carter 2006-2008
   5  *
   6  * This program is free software; you can redistribute it and/or modify
   7  * it under the terms of the GNU General Public License as published by
   8  * the Free Software Foundation; either version 2 of the License, or
   9  * (at your option) any later version.
  10  *
  11  * This program is distributed in the hope that it will be useful,
  12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  * GNU General Public License for more details.
  15  *
  16  * You should have received a copy of the GNU General Public License
  17  * along with this program; if not, write to the Free Software
  18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19  */
  20 
  21 #include "includes.h"
  22 #include "idmap_adex.h"
  23 
  24 #undef DBGC_CLASS
  25 #define DBGC_CLASS DBGC_IDMAP
  26 
  27 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
  28 
  29 NTSTATUS init_module(void);
  30 
  31 /*
  32  * IdMap backend
  33  */
  34 
  35 /********************************************************************
  36  Basic init function responsible for determining our current mode
  37  (standalone or using Centeris Cells).  This must return success or
  38  it will be dropped from the idmap backend list.
  39  *******************************************************************/
  40 
  41 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
     /* [<][>][^][v][top][bottom][index][help] */
  42                                      const char *params)
  43 {
  44         ADS_STRUCT *ads = NULL;
  45         ADS_STATUS status;
  46         static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
  47         DOM_SID domain_sid;
  48         fstring dcname;
  49         struct sockaddr_storage ip;
  50         struct likewise_cell *lwcell;
  51 
  52         if (NT_STATUS_IS_OK(init_status))
  53                 return NT_STATUS_OK;
  54 
  55         /* Silently fail if we are not a member server in security = ads */
  56 
  57         if ((lp_server_role() != ROLE_DOMAIN_MEMBER) ||
  58             (lp_security() != SEC_ADS)) {
  59                 init_status = NT_STATUS_INVALID_SERVER_STATE;
  60                 BAIL_ON_NTSTATUS_ERROR(init_status);
  61         }
  62 
  63         /* fetch our domain SID first */
  64 
  65         if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
  66                 init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
  67                 BAIL_ON_NTSTATUS_ERROR(init_status);
  68         }
  69 
  70         /* reuse the same ticket cache as winbindd */
  71 
  72         setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
  73 
  74         /* Establish a connection to a DC */
  75 
  76         if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) {
  77                 init_status = NT_STATUS_NO_MEMORY;
  78                 BAIL_ON_NTSTATUS_ERROR(init_status);
  79         }
  80 
  81         ads->auth.password =
  82             secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
  83         ads->auth.realm = SMB_STRDUP(lp_realm());
  84 
  85         /* get the DC name here to setup the server affinity cache and
  86            local krb5.conf */
  87 
  88         get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip);
  89 
  90         status = ads_connect(ads);
  91         if (!ADS_ERR_OK(status)) {
  92                 DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n",
  93                           ads_errstr(status)));
  94         }
  95         init_status = ads_ntstatus(status);
  96         BAIL_ON_NTSTATUS_ERROR(init_status);
  97 
  98 
  99         /* Find out cell membership */
 100 
 101         init_status = cell_locate_membership(ads);
 102         if (!NT_STATUS_IS_OK(init_status)) {
 103                 DEBUG(0,("LWI: Fail to locate cell membership (%s).",
 104                          nt_errstr(init_status)));
 105                 goto done;
 106         }
 107 
 108         /* Fill in the cell information */
 109 
 110         lwcell = cell_list_head();
 111 
 112         init_status = cell_lookup_settings(lwcell);
 113         BAIL_ON_NTSTATUS_ERROR(init_status);
 114 
 115         /* Miscellaneous setup.  E.g. set up the list of GC
 116            servers and domain list for our forest (does not actually
 117            connect). */
 118 
 119         init_status = gc_init_list();
 120         BAIL_ON_NTSTATUS_ERROR(init_status);
 121 
 122         init_status = domain_init_list();
 123         BAIL_ON_NTSTATUS_ERROR(init_status);
 124 
 125 done:
 126         if (!NT_STATUS_IS_OK(init_status)) {
 127                 DEBUG(1,("Likewise initialization failed (%s)\n",
 128                          nt_errstr(init_status)));
 129         }
 130 
 131         /* cleanup */
 132 
 133         if (!NT_STATUS_IS_OK(init_status)) {
 134                 cell_list_destroy();
 135 
 136                 /* init_status stores the failure reason but we need to
 137                    return success or else idmap_init() will drop us from the
 138                    backend list */
 139                 return NT_STATUS_OK;
 140         }
 141 
 142         init_status = NT_STATUS_OK;
 143 
 144         return init_status;
 145 }
 146 
 147 /**********************************************************************
 148  *********************************************************************/
 149 
 150 static NTSTATUS _idmap_adex_get_sid_from_id(struct
     /* [<][>][^][v][top][bottom][index][help] */
 151                                                 idmap_domain
 152                                                 *dom, struct
 153                                                 id_map
 154                                                 **ids)
 155 {
 156         int i;
 157         bool one_mapped = false;
 158         bool all_mapped = true;
 159         NTSTATUS nt_status;
 160         struct likewise_cell *cell;
 161 
 162         /* initialize the status to avoid suprise */
 163         for (i = 0; ids[i]; i++) {
 164                 ids[i]->status = ID_UNKNOWN;
 165         }
 166         
 167         nt_status = _idmap_adex_init(dom, NULL);
 168         if (!NT_STATUS_IS_OK(nt_status))
 169                 return nt_status;
 170 
 171         if ((cell = cell_list_head()) == NULL) {
 172                 return NT_STATUS_INVALID_SERVER_STATE;
 173         }
 174 
 175         /* have to work through these one by one */
 176         for (i = 0; ids[i]; i++) {
 177                 NTSTATUS status;
 178                 status = cell->provider->get_sid_from_id(ids[i]->sid,
 179                                                          ids[i]->xid.id,
 180                                                          ids[i]->xid.type);
 181                 /* Fail if we cannot find any DC */
 182                 if (NT_STATUS_EQUAL
 183                     (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
 184                         return status;
 185                 }
 186 
 187                 if (!NT_STATUS_IS_OK(status)) {
 188                         ids[i]->status = ID_UNMAPPED;
 189                         all_mapped = false;
 190                         continue;
 191                 }
 192 
 193                 ids[i]->status = ID_MAPPED;
 194                 one_mapped = true;
 195         }
 196 
 197         return NT_STATUS_OK;
 198 }
 199 
 200 /**********************************************************************
 201  *********************************************************************/
 202 
 203 static NTSTATUS _idmap_adex_get_id_from_sid(struct
     /* [<][>][^][v][top][bottom][index][help] */
 204                                                 idmap_domain
 205                                                 *dom, struct
 206                                                 id_map
 207                                                 **ids)
 208 {
 209         int i;
 210         bool one_mapped = false;
 211         bool all_mapped = true;
 212         NTSTATUS nt_status;
 213         struct likewise_cell *cell;
 214 
 215         /* initialize the status to avoid suprise */
 216         for (i = 0; ids[i]; i++) {
 217                 ids[i]->status = ID_UNKNOWN;
 218         }
 219         
 220         nt_status = _idmap_adex_init(dom, NULL);
 221         if (!NT_STATUS_IS_OK(nt_status))
 222                 return nt_status;
 223 
 224         if ((cell = cell_list_head()) == NULL) {
 225                 return NT_STATUS_INVALID_SERVER_STATE;
 226         }
 227 
 228         /* have to work through these one by one */
 229         for (i = 0; ids[i]; i++) {
 230                 NTSTATUS status;
 231                 status = cell->provider->get_id_from_sid(&ids[i]->xid.id,
 232                                                          &ids[i]->xid.
 233                                                          type, ids[i]->sid);
 234                 /* Fail if we cannot find any DC */
 235                 if (NT_STATUS_EQUAL
 236                     (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
 237                         return status;
 238                 }
 239 
 240                 if (!NT_STATUS_IS_OK(status)) {
 241                         ids[i]->status = ID_UNMAPPED;
 242                         all_mapped = false;
 243                         continue;
 244                 }
 245 
 246                 ids[i]->status = ID_MAPPED;
 247                 one_mapped = true;
 248         }
 249 
 250         return NT_STATUS_OK;
 251 }
 252 
 253 /**********************************************************************
 254  *********************************************************************/
 255 
 256 static NTSTATUS _idmap_adex_set_mapping(struct
     /* [<][>][^][v][top][bottom][index][help] */
 257                                             idmap_domain
 258                                             *dom, const struct
 259                                             id_map *map)
 260 {
 261         DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
 262         return NT_STATUS_NOT_IMPLEMENTED;
 263 }
 264 
 265 /**********************************************************************
 266  *********************************************************************/
 267 
 268 static NTSTATUS _idmap_adex_remove_mapping(struct
     /* [<][>][^][v][top][bottom][index][help] */
 269                                                idmap_domain
 270                                                *dom, const
 271                                                struct
 272                                                id_map
 273                                                *map)
 274 {
 275         DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
 276         return NT_STATUS_NOT_IMPLEMENTED;
 277 }
 278 
 279 /**********************************************************************
 280  *********************************************************************/
 281 
 282 static NTSTATUS _idmap_adex_dump(struct idmap_domain
     /* [<][>][^][v][top][bottom][index][help] */
 283                                      *dom, struct id_map **maps, int *num_map)
 284 {
 285         return NT_STATUS_NOT_IMPLEMENTED;
 286 }
 287 
 288 /**********************************************************************
 289  *********************************************************************/
 290 
 291 static NTSTATUS _idmap_adex_close(struct idmap_domain
     /* [<][>][^][v][top][bottom][index][help] */
 292                                       *dom)
 293 {
 294         /* FIXME!  need to do cleanup here */
 295 
 296         return NT_STATUS_OK;
 297 }
 298 
 299 /*
 300  * IdMap NSS plugin
 301  */
 302 
 303 /**********************************************************************
 304  *********************************************************************/
 305 
 306 static NTSTATUS _nss_adex_init(struct nss_domain_entry
     /* [<][>][^][v][top][bottom][index][help] */
 307                                   *e)
 308 {
 309         return _idmap_adex_init(NULL, NULL);
 310 }
 311 
 312 /**********************************************************************
 313  *********************************************************************/
 314 
 315 static NTSTATUS _nss_adex_get_info(struct
     /* [<][>][^][v][top][bottom][index][help] */
 316                                       nss_domain_entry *e,
 317                                       const DOM_SID * sid,
 318                                       TALLOC_CTX * ctx,
 319                                       ADS_STRUCT * ads,
 320                                       LDAPMessage * msg,
 321                                       char **homedir,
 322                                       char **shell, char **gecos, gid_t * p_gid)
 323 {
 324         NTSTATUS nt_status;
 325         struct likewise_cell *cell;
 326 
 327         nt_status = _idmap_adex_init(NULL, NULL);
 328         if (!NT_STATUS_IS_OK(nt_status))
 329                 return nt_status;
 330 
 331         if ((cell = cell_list_head()) == NULL) {
 332                 return NT_STATUS_INVALID_SERVER_STATE;
 333         }
 334 
 335         return cell->provider->get_nss_info(sid, ctx, homedir,
 336                                             shell, gecos, p_gid);
 337 }
 338 
 339 /**********************************************************************
 340  *********************************************************************/
 341 
 342 static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 343                                        struct nss_domain_entry *e,
 344                                        const char *name, char **alias)
 345 {
 346         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 347         struct likewise_cell *cell = NULL;
 348 
 349         nt_status = _idmap_adex_init(NULL, NULL);
 350         BAIL_ON_NTSTATUS_ERROR(nt_status);
 351 
 352         if ((cell = cell_list_head()) == NULL) {
 353                 nt_status = NT_STATUS_INVALID_SERVER_STATE;
 354                 BAIL_ON_NTSTATUS_ERROR(nt_status);
 355         }
 356 
 357         nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
 358                                                  name, alias);
 359 
 360         /* go ahead and allow the cache mgr to mark this in
 361            negative cache */
 362 
 363         if (!NT_STATUS_IS_OK(nt_status))
 364                 nt_status = NT_STATUS_NONE_MAPPED;
 365 
 366 done:
 367         return nt_status;
 368 }
 369 
 370 /**********************************************************************
 371  *********************************************************************/
 372 
 373 static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 374                                          struct nss_domain_entry *e,
 375                                          const char *alias, char **name)
 376 {
 377         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 378         struct likewise_cell *cell = NULL;
 379 
 380         nt_status = _idmap_adex_init(NULL, NULL);
 381         BAIL_ON_NTSTATUS_ERROR(nt_status);
 382 
 383         if ((cell = cell_list_head()) == NULL) {
 384                 nt_status = NT_STATUS_INVALID_SERVER_STATE;
 385                 BAIL_ON_NTSTATUS_ERROR(nt_status);
 386         }
 387 
 388 
 389         nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
 390                                                    alias, name);
 391 
 392         /* go ahead and allow the cache mgr to mark this in
 393            negative cache */
 394 
 395         if (!NT_STATUS_IS_OK(nt_status))
 396                 nt_status = NT_STATUS_NONE_MAPPED;
 397 
 398 done:
 399         return nt_status;
 400 }
 401 
 402 /**********************************************************************
 403  *********************************************************************/
 404 
 405 static NTSTATUS _nss_adex_close(void)
     /* [<][>][^][v][top][bottom][index][help] */
 406 {
 407         return NT_STATUS_NOT_IMPLEMENTED;
 408 }
 409 
 410 /**********************************************************************
 411  *********************************************************************/
 412 
 413 static struct idmap_methods adex_idmap_methods = {
 414 
 415         .init             = _idmap_adex_init,
 416         .unixids_to_sids  = _idmap_adex_get_sid_from_id,
 417         .sids_to_unixids  = _idmap_adex_get_id_from_sid,
 418         .set_mapping      = _idmap_adex_set_mapping,
 419         .remove_mapping   = _idmap_adex_remove_mapping,
 420         .dump_data        = _idmap_adex_dump,
 421         .close_fn         = _idmap_adex_close
 422 };
 423 static struct nss_info_methods adex_nss_methods = {
 424         .init           = _nss_adex_init,
 425         .get_nss_info   = _nss_adex_get_info,
 426         .map_to_alias   = _nss_adex_map_to_alias,
 427         .map_from_alias = _nss_adex_map_from_alias,
 428         .close_fn       = _nss_adex_close
 429 };
 430 
 431 /**********************************************************************
 432  Register with the idmap and idmap_nss subsystems. We have to protect
 433  against the idmap and nss_info interfaces being in a half-registered
 434  state.
 435  **********************************************************************/
 436 NTSTATUS idmap_adex_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 437 {
 438         static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
 439         static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
 440         if (!NT_STATUS_IS_OK(idmap_status)) {
 441                 idmap_status =
 442                     smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
 443                                        "adex", &adex_idmap_methods);
 444                 if (!NT_STATUS_IS_OK(idmap_status)) {
 445                         DEBUG(0,
 446                               ("idmap_centeris_init: Failed to register the adex"
 447                                "idmap plugin.\n"));
 448                         return idmap_status;
 449                 }
 450         }
 451 
 452         if (!NT_STATUS_IS_OK(nss_status)) {
 453                 nss_status =
 454                     smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
 455                                            "adex", &adex_nss_methods);
 456                 if (!NT_STATUS_IS_OK(nss_status)) {
 457                         DEBUG(0,
 458                               ("idmap_adex_init: Failed to register the adex"
 459                                "nss plugin.\n"));
 460                         return nss_status;
 461                 }
 462         }
 463 
 464         return NT_STATUS_OK;
 465 }
 466 
 467 static NTSTATUS nss_info_adex_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 468 {
 469         return idmap_adex_init();
 470 }

/* [<][>][^][v][top][bottom][index][help] */