LCOV - code coverage report
Current view: top level - source3/winbindd - nss_info.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 147 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Idmap NSS headers
       4             : 
       5             :    Copyright (C) Gerald Carter             2006
       6             :    Copyright (C) Michael Adam 2008
       7             : 
       8             :    This library is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU Lesser General Public
      10             :    License as published by the Free Software Foundation; either
      11             :    version 3 of the License, or (at your option) any later version.
      12             : 
      13             :    This library is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    Library General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU Lesser General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "nss_info.h"
      24             : 
      25             : static struct nss_function_entry *backends = NULL;
      26             : static struct nss_function_entry *default_backend = NULL;
      27             : static struct nss_domain_entry *nss_domain_list = NULL;
      28             : 
      29             : /**********************************************************************
      30             :  Get idmap nss methods.
      31             : **********************************************************************/
      32             : 
      33           0 : static struct nss_function_entry *nss_get_backend(const char *name )
      34             : {
      35           0 :         struct nss_function_entry *entry = NULL;
      36             : 
      37           0 :         for(entry = backends; entry; entry = entry->next) {
      38           0 :                 if ( strequal(entry->name, name) )
      39           0 :                         return entry;
      40             :         }
      41             : 
      42           0 :         return NULL;
      43             : }
      44             : 
      45             : /*********************************************************************
      46             :  Allow a module to register itself as a backend.
      47             : **********************************************************************/
      48             : 
      49           0 :  NTSTATUS smb_register_idmap_nss(int version, const char *name,
      50             :                                  const struct nss_info_methods *methods)
      51             : {
      52           0 :         struct nss_function_entry *entry;
      53             : 
      54           0 :         if ((version != SMB_NSS_INFO_INTERFACE_VERSION)) {
      55           0 :                 DEBUG(0, ("smb_register_idmap_nss: Failed to register idmap_nss module.\n"
      56             :                           "The module was compiled against SMB_NSS_INFO_INTERFACE_VERSION %d,\n"
      57             :                           "current SMB_NSS_INFO_INTERFACE_VERSION is %d.\n"
      58             :                           "Please recompile against the current version of samba!\n",
      59             :                           version, SMB_NSS_INFO_INTERFACE_VERSION));
      60           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
      61             :         }
      62             : 
      63           0 :         if (!name || !name[0] || !methods) {
      64           0 :                 DEBUG(0,("smb_register_idmap_nss: called with NULL pointer or empty name!\n"));
      65           0 :                 return NT_STATUS_INVALID_PARAMETER;
      66             :         }
      67             : 
      68           0 :         if ( nss_get_backend(name) ) {
      69           0 :                 DEBUG(5,("smb_register_idmap_nss: idmap module %s "
      70             :                          "already registered!\n", name));
      71           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
      72             :         }
      73             : 
      74           0 :         entry = SMB_XMALLOC_P(struct nss_function_entry);
      75           0 :         entry->name = smb_xstrdup(name);
      76           0 :         entry->methods = methods;
      77             : 
      78           0 :         DLIST_ADD(backends, entry);
      79           0 :         DEBUG(5, ("smb_register_idmap_nss: Successfully added idmap "
      80             :                   "nss backend '%s'\n", name));
      81             : 
      82           0 :         return NT_STATUS_OK;
      83             : }
      84             : 
      85             : /********************************************************************
      86             :  *******************************************************************/
      87             : 
      88           0 : static bool parse_nss_parm(TALLOC_CTX *mem_ctx,
      89             :                            const char *config,
      90             :                            char **backend,
      91             :                            char **domain)
      92             : {
      93           0 :         char *p;
      94             : 
      95           0 :         *backend = *domain = NULL;
      96             : 
      97           0 :         if ( !config )
      98           0 :                 return False;
      99             : 
     100           0 :         p = strchr( config, ':' );
     101             : 
     102             :         /* if no : then the string must be the backend name only */
     103             : 
     104           0 :         if ( !p ) {
     105           0 :                 *backend = talloc_strdup(mem_ctx, config);
     106           0 :                 return (*backend != NULL);
     107             :         }
     108             : 
     109             :         /* split the string and return the two parts */
     110             : 
     111           0 :         if ( strlen(p+1) > 0 ) {
     112           0 :                 *domain = talloc_strdup(mem_ctx, p + 1);
     113             :         }
     114             : 
     115           0 :         *backend = talloc_strndup(mem_ctx, config, PTR_DIFF(p, config));
     116           0 :         return (*backend != NULL);
     117             : }
     118             : 
     119           0 : static NTSTATUS nss_domain_list_add_domain(const char *domain,
     120             :                                            struct nss_function_entry *nss_backend)
     121             : {
     122           0 :         struct nss_domain_entry *nss_domain;
     123             : 
     124           0 :         nss_domain = talloc_zero(nss_domain_list, struct nss_domain_entry);
     125           0 :         if (!nss_domain) {
     126           0 :                 DEBUG(0, ("nss_domain_list_add_domain: talloc() failure!\n"));
     127           0 :                 return NT_STATUS_NO_MEMORY;
     128             :         }
     129             : 
     130           0 :         nss_domain->backend = nss_backend;
     131           0 :         if (domain) {
     132           0 :                 nss_domain->domain  = talloc_strdup(nss_domain, domain);
     133           0 :                 if (!nss_domain->domain) {
     134           0 :                         DEBUG(0, ("nss_domain_list_add_domain: talloc() "
     135             :                                   "failure!\n"));
     136           0 :                         TALLOC_FREE(nss_domain);
     137           0 :                         return NT_STATUS_NO_MEMORY;
     138             :                 }
     139             :         }
     140             : 
     141           0 :         nss_domain->init_status = nss_domain->backend->methods->init(nss_domain);
     142           0 :         if (!NT_STATUS_IS_OK(nss_domain->init_status))  {
     143           0 :                 DEBUG(0, ("nss_init: Failed to init backend '%s' for domain "
     144             :                           "'%s'!\n", nss_backend->name, nss_domain->domain));
     145             :         }
     146             : 
     147           0 :         DLIST_ADD(nss_domain_list, nss_domain);
     148             : 
     149           0 :         DEBUG(10, ("Added domain '%s' with backend '%s' to nss_domain_list.\n",
     150             :                    domain, nss_backend->name));
     151             : 
     152           0 :         return NT_STATUS_OK;
     153             : }
     154             : 
     155             : /********************************************************************
     156             :  Each nss backend must not store global state, but rather be able
     157             :  to initialize the state on a per domain basis.
     158             :  *******************************************************************/
     159             : 
     160           0 : static NTSTATUS nss_init(const char **nss_list)
     161             : {
     162           0 :         NTSTATUS status;
     163           0 :         static bool nss_initialized = false;
     164           0 :         int i;
     165           0 :         char *backend = NULL, *domain = NULL;
     166           0 :         struct nss_function_entry *nss_backend;
     167           0 :         TALLOC_CTX *frame;
     168             : 
     169             :         /* check for previous successful initializations */
     170             : 
     171           0 :         if (nss_initialized) {
     172           0 :                 return NT_STATUS_OK;
     173             :         }
     174             : 
     175           0 :         frame = talloc_stackframe();
     176             : 
     177             :         /* The "template" backend should always be registered as it
     178             :            is a static module */
     179             : 
     180           0 :         nss_backend = nss_get_backend("template");
     181           0 :         if (nss_backend == NULL) {
     182           0 :                 static_init_nss_info(NULL);
     183             :         }
     184             : 
     185             :         /* Create the list of nss_domains (loading any shared plugins
     186             :            as necessary) */
     187             : 
     188           0 :         for ( i=0; nss_list && nss_list[i]; i++ ) {
     189           0 :                 bool ok;
     190             : 
     191           0 :                 ok = parse_nss_parm(frame, nss_list[i], &backend, &domain);
     192           0 :                 if (!ok) {
     193           0 :                         DEBUG(0,("nss_init: failed to parse \"%s\"!\n",
     194             :                                  nss_list[i]));
     195           0 :                         continue;
     196             :                 }
     197             : 
     198           0 :                 DEBUG(10, ("parsed backend = '%s', domain = '%s'\n",
     199             :                            backend, domain));
     200             : 
     201             :                 /* validate the backend */
     202             : 
     203           0 :                 nss_backend = nss_get_backend(backend);
     204           0 :                 if (nss_backend == NULL) {
     205             :                         /*
     206             :                          * This is a freaking hack. We don't have proper
     207             :                          * modules for nss_info backends. Right now we have
     208             :                          * our standard nss_info backends in the ad backend.
     209             :                          */
     210           0 :                         status = smb_probe_module("idmap", "ad");
     211           0 :                         if ( !NT_STATUS_IS_OK(status) ) {
     212           0 :                                 continue;
     213             :                         }
     214             :                 }
     215             : 
     216           0 :                 nss_backend = nss_get_backend(backend);
     217           0 :                 if (nss_backend == NULL) {
     218             :                         /* attempt to register the backend */
     219           0 :                         status = smb_probe_module( "nss_info", backend );
     220           0 :                         if ( !NT_STATUS_IS_OK(status) ) {
     221           0 :                                 continue;
     222             :                         }
     223             :                 }
     224             : 
     225             :                 /* try again */
     226           0 :                 nss_backend = nss_get_backend(backend);
     227           0 :                 if (nss_backend == NULL) {
     228           0 :                         DEBUG(0, ("nss_init: unregistered backend %s!. "
     229             :                                   "Skipping\n", backend));
     230           0 :                         continue;
     231             :                 }
     232             : 
     233             :                 /*
     234             :                  * The first config item of the list without an explicit domain
     235             :                  * is treated as the default nss info backend.
     236             :                  */
     237           0 :                 if ((domain == NULL) && (default_backend == NULL)) {
     238           0 :                         DEBUG(10, ("nss_init: using '%s' as default backend.\n",
     239             :                                    backend));
     240           0 :                         default_backend = nss_backend;
     241             :                 }
     242             : 
     243           0 :                 status = nss_domain_list_add_domain(domain, nss_backend);
     244           0 :                 if (!NT_STATUS_IS_OK(status)) {
     245           0 :                         return status;
     246             :                 }
     247             : 
     248             :                 /* cleanup */
     249             : 
     250           0 :                 TALLOC_FREE(domain);
     251           0 :                 TALLOC_FREE(backend);
     252             :         }
     253             : 
     254             : 
     255           0 :         if ( !nss_domain_list ) {
     256           0 :                 DEBUG(3,("nss_init: no nss backends configured.  "
     257             :                          "Defaulting to \"template\".\n"));
     258             : 
     259             : 
     260             :                 /* we should default to use template here */
     261             :         }
     262             : 
     263           0 :         nss_initialized = true;
     264             : 
     265           0 :         TALLOC_FREE(frame);
     266           0 :         return NT_STATUS_OK;
     267             : }
     268             : 
     269             : /********************************************************************
     270             :  *******************************************************************/
     271             : 
     272           0 : static struct nss_domain_entry *find_nss_domain( const char *domain )
     273             : {
     274           0 :         NTSTATUS status;
     275           0 :         struct nss_domain_entry *p;
     276             : 
     277           0 :         status = nss_init( lp_winbind_nss_info() );
     278           0 :         if ( !NT_STATUS_IS_OK(status) ) {
     279           0 :                 DEBUG(4,("find_nss_domain: Failed to init nss_info API "
     280             :                          "(%s)!\n", nt_errstr(status)));
     281           0 :                 return NULL;
     282             :         }
     283             : 
     284           0 :         for ( p=nss_domain_list; p; p=p->next ) {
     285           0 :                 if ( strequal( p->domain, domain ) )
     286           0 :                         break;
     287             :         }
     288             : 
     289             :         /* If we didn't find a match, then use the default nss backend */
     290             : 
     291           0 :         if ( !p ) {
     292           0 :                 if (!default_backend) {
     293           0 :                         return NULL;
     294             :                 }
     295             : 
     296           0 :                 status = nss_domain_list_add_domain(domain, default_backend);
     297           0 :                 if (!NT_STATUS_IS_OK(status)) {
     298           0 :                         return NULL;
     299             :                 }
     300             : 
     301             :                 /*
     302             :                  * HACK ALERT:
     303             :                  * Here, we use the fact that the new domain was added at
     304             :                  * the beginning of the list...
     305             :                  */
     306           0 :                 p = nss_domain_list;
     307             :         }
     308             : 
     309           0 :         if ( !NT_STATUS_IS_OK( p->init_status ) ) {
     310           0 :                p->init_status = p->backend->methods->init( p );
     311             :         }
     312             : 
     313           0 :         return p;
     314             : }
     315             : 
     316             : /********************************************************************
     317             :  *******************************************************************/
     318             : 
     319           0 :  NTSTATUS nss_map_to_alias( TALLOC_CTX *mem_ctx, const char *domain,
     320             :                             const char *name, char **alias )
     321             : {
     322           0 :         struct nss_domain_entry *p;
     323           0 :         const struct nss_info_methods *m;
     324             : 
     325           0 :         if ( (p = find_nss_domain( domain )) == NULL ) {
     326           0 :                 DEBUG(4,("nss_map_to_alias: Failed to find nss domain pointer for %s\n",
     327             :                          domain ));
     328           0 :                 return NT_STATUS_NOT_FOUND;
     329             :         }
     330             : 
     331           0 :         m = p->backend->methods;
     332             : 
     333           0 :         return m->map_to_alias(mem_ctx, p, name, alias);
     334             : }
     335             : 
     336             : 
     337             : /********************************************************************
     338             :  *******************************************************************/
     339             : 
     340           0 :  NTSTATUS nss_map_from_alias( TALLOC_CTX *mem_ctx, const char *domain,
     341             :                               const char *alias, char **name )
     342             : {
     343           0 :         struct nss_domain_entry *p;
     344           0 :         const struct nss_info_methods *m;
     345             : 
     346           0 :         if ( (p = find_nss_domain( domain )) == NULL ) {
     347           0 :                 DEBUG(4,("nss_map_from_alias: Failed to find nss domain pointer for %s\n",
     348             :                          domain ));
     349           0 :                 return NT_STATUS_NOT_FOUND;
     350             :         }
     351             : 
     352           0 :         m = p->backend->methods;
     353             : 
     354           0 :         return m->map_from_alias( mem_ctx, p, alias, name );
     355             : }
     356             : 
     357             : /********************************************************************
     358             :  *******************************************************************/
     359             : 
     360           0 :  NTSTATUS nss_close( const char *parameters )
     361             : {
     362           0 :         struct nss_domain_entry *p = nss_domain_list;
     363           0 :         struct nss_domain_entry *q;
     364             : 
     365           0 :         while ( p && p->backend && p->backend->methods ) {
     366             :                 /* close the backend */
     367           0 :                 p->backend->methods->close_fn();
     368             : 
     369             :                 /* free the memory */
     370           0 :                 q = p;
     371           0 :                 p = p->next;
     372           0 :                 TALLOC_FREE( q );
     373             :         }
     374             : 
     375           0 :         return NT_STATUS_OK;
     376             : }
     377             : 

Generated by: LCOV version 1.14