nsswitch/nss_info.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Idmap NSS headers
00004 
00005    Copyright (C) Gerald Carter             2006
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011    
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016    
00017    You should have received a copy of the GNU Library General Public
00018    License along with this library; if not, write to the
00019    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020    Boston, MA  02111-1307, USA.   
00021 */
00022 
00023 #include "includes.h"
00024 #include "nss_info.h"
00025 
00026 static struct nss_function_entry *backends = NULL;
00027 static struct nss_domain_entry *nss_domain_list = NULL;
00028 
00029 /**********************************************************************
00030  Get idmap nss methods.
00031 **********************************************************************/
00032 
00033 static struct nss_function_entry *nss_get_backend(const char *name )
00034 {
00035         struct nss_function_entry *entry = backends;
00036 
00037         for(entry = backends; entry; entry = entry->next) {
00038                 if ( strequal(entry->name, name) )
00039                         return entry;
00040         }
00041 
00042         return NULL;
00043 }
00044 
00045 /*********************************************************************
00046  Allow a module to register itself as a backend.
00047 **********************************************************************/
00048 
00049  NTSTATUS smb_register_idmap_nss(int version, const char *name, struct nss_info_methods *methods)
00050 {
00051         struct nss_function_entry *entry;
00052 
00053         if ((version != SMB_NSS_INFO_INTERFACE_VERSION)) {
00054                 DEBUG(0, ("smb_register_idmap_nss: Failed to register idmap_nss module.\n"
00055                           "The module was compiled against SMB_NSS_INFO_INTERFACE_VERSION %d,\n"
00056                           "current SMB_NSS_INFO_INTERFACE_VERSION is %d.\n"
00057                           "Please recompile against the current version of samba!\n",  
00058                           version, SMB_NSS_INFO_INTERFACE_VERSION));
00059                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
00060         }
00061 
00062         if (!name || !name[0] || !methods) {
00063                 DEBUG(0,("smb_register_idmap_nss: called with NULL pointer or empty name!\n"));
00064                 return NT_STATUS_INVALID_PARAMETER;
00065         }
00066 
00067         if ( nss_get_backend(name) ) {
00068                 DEBUG(0,("smb_register_idmap_nss: idmap module %s "
00069                          "already registered!\n", name));
00070                 return NT_STATUS_OBJECT_NAME_COLLISION;
00071         }
00072 
00073         entry = SMB_XMALLOC_P(struct nss_function_entry);
00074         entry->name = smb_xstrdup(name);
00075         entry->methods = methods;
00076 
00077         DLIST_ADD(backends, entry);
00078         DEBUG(5, ("smb_register_idmap_nss: Successfully added idmap "
00079                   "nss backend '%s'\n", name));
00080 
00081         return NT_STATUS_OK;
00082 }
00083 
00084 /********************************************************************
00085  *******************************************************************/
00086 
00087 static BOOL parse_nss_parm( const char *config, char **backend, char **domain )
00088 {
00089         char *p;
00090         char *q;
00091         int len;
00092 
00093         *backend = *domain = NULL;
00094         
00095         if ( !config )
00096                 return False;
00097         
00098         p = strchr( config, ':' );
00099         
00100         /* if no : then the string must be the backend name only */
00101 
00102         if ( !p ) {
00103                 *backend = SMB_STRDUP( config );
00104                 return (*backend != NULL);
00105         }
00106 
00107         /* split the string and return the two parts */
00108 
00109         if ( strlen(p+1) > 0 ) {
00110                 *domain = SMB_STRDUP( p+1 );
00111         }
00112         
00113         len = PTR_DIFF(p,config)+1;
00114         if ( (q = SMB_MALLOC_ARRAY( char, len )) == NULL ) {
00115                 SAFE_FREE( *backend );
00116                 return False;
00117         }
00118         
00119         StrnCpy( q, config, len-1);
00120         q[len-1] = '\0';
00121         *backend = q;
00122 
00123         return True;
00124 }
00125 
00126 /********************************************************************
00127  Each nss backend must not store global state, but rather be able 
00128  to initialize the state on a per domain basis.
00129  *******************************************************************/
00130 
00131  NTSTATUS nss_init( const char **nss_list )
00132 {
00133         NTSTATUS status;
00134         static NTSTATUS nss_initialized = NT_STATUS_UNSUCCESSFUL;
00135         int i;
00136         char *backend, *domain;
00137         struct nss_function_entry *nss_backend;
00138         struct nss_domain_entry *nss_domain;
00139 
00140         /* check for previous successful initializations */
00141 
00142         if ( NT_STATUS_IS_OK(nss_initialized) )
00143                 return NT_STATUS_OK;
00144         
00145         /* The "template" backend should alqays be registered as it
00146            is a static module */
00147 
00148         if ( (nss_backend = nss_get_backend( "template" )) == NULL ) {
00149                 static_init_nss_info;          
00150         }
00151 
00152         /* Create the list of nss_domains (loading any shared plugins
00153            as necessary) */
00154 
00155         for ( i=0; nss_list && nss_list[i]; i++ ) {
00156 
00157                 if ( !parse_nss_parm(nss_list[i], &backend, &domain) )  {
00158                         DEBUG(0,("nss_init: failed to parse \"%s\"!\n",
00159                                  nss_list[i]));
00160                         continue;                       
00161                 }
00162 
00163                 /* validate the backend */
00164 
00165                 if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
00166                         /* attempt to register the backend */
00167                         status = smb_probe_module( "nss_info", backend );
00168                         if ( !NT_STATUS_IS_OK(status) ) {
00169                                 continue;
00170                         }
00171                         
00172                         /* try again */
00173                         if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
00174                                 DEBUG(0,("nss_init: unregistered backend %s!.  Skipping\n",
00175                                          backend));
00176                                 continue;
00177                         }
00178 
00179                 }
00180 
00181                 /* fill in the nss_domain_entry and add it to the 
00182                    list of domains */
00183 
00184                 nss_domain = TALLOC_ZERO_P( nss_domain_list, struct nss_domain_entry );
00185                 if ( !nss_domain ) {
00186                         DEBUG(0,("nss_init: talloc() failure!\n"));
00187                         return NT_STATUS_NO_MEMORY;
00188                 }
00189                 
00190                 nss_domain->backend = nss_backend;
00191                 nss_domain->domain  = talloc_strdup( nss_domain, domain );
00192 
00193                 status = nss_domain->backend->methods->init( nss_domain );
00194                 if ( NT_STATUS_IS_OK( status ) ) {
00195                         DLIST_ADD( nss_domain_list, nss_domain );
00196                 } else {
00197                         DEBUG(0,("nss_init: Failed to init backend for %s domain!\n", 
00198                                  nss_domain->domain));
00199                 }
00200 
00201                 /* cleanup */
00202 
00203                 SAFE_FREE( backend );
00204                 SAFE_FREE( domain );            
00205         }
00206 
00207         if ( !nss_domain_list ) {
00208                 DEBUG(3,("nss_init: no nss backends configured.  "
00209                          "Defaulting to \"template\".\n"));
00210 
00211 
00212                 /* we shouild default to use template here */
00213         }
00214         
00215                 
00216         nss_initialized = NT_STATUS_OK;
00217         
00218         return NT_STATUS_OK;
00219 }
00220 
00221 /********************************************************************
00222  *******************************************************************/
00223 
00224 static struct nss_domain_entry *find_nss_domain( const char *domain )
00225 {
00226         NTSTATUS status;        
00227         struct nss_domain_entry *p;
00228 
00229         status = nss_init( lp_winbind_nss_info() );
00230         if ( !NT_STATUS_IS_OK(status) ) {
00231                 DEBUG(4,("nss_get_info: Failed to init nss_info API (%s)!\n",
00232                          nt_errstr(status)));
00233                 return NULL;
00234         }
00235         
00236         for ( p=nss_domain_list; p; p=p->next ) {
00237                 if ( strequal( p->domain, domain ) )
00238                         break;
00239         }
00240         
00241         /* If we didn't find a match, then use the default nss info */
00242 
00243         if ( !p ) {
00244                 if ( !nss_domain_list ) {
00245                         return NULL;
00246                 }
00247                 
00248                 p = nss_domain_list;            
00249         }
00250 
00251         return p;
00252 }
00253 
00254 /********************************************************************
00255  *******************************************************************/
00256 
00257  NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
00258                        TALLOC_CTX *ctx,
00259                        ADS_STRUCT *ads, LDAPMessage *msg,
00260                        char **homedir, char **shell, char **gecos,
00261                        gid_t *p_gid)
00262 {
00263         struct nss_domain_entry *p;
00264         struct nss_info_methods *m;
00265 
00266         if ( (p = find_nss_domain( domain )) == NULL ) {
00267                 DEBUG(4,("nss_get_info: Failed to find nss domain pointer for %s\n",
00268                          domain ));
00269                 return NT_STATUS_NOT_FOUND;
00270         }
00271                 
00272         m = p->backend->methods;
00273 
00274         return m->get_nss_info( p, user_sid, ctx, ads, msg, 
00275                                 homedir, shell, gecos, p_gid );
00276 }
00277 
00278 /********************************************************************
00279  *******************************************************************/
00280 
00281  NTSTATUS nss_close( const char *parameters )
00282 {
00283         struct nss_domain_entry *p = nss_domain_list;
00284         struct nss_domain_entry *q;
00285 
00286         while ( p && p->backend && p->backend->methods ) {
00287                 /* close the backend */
00288                 p->backend->methods->close_fn();
00289 
00290                 /* free the memory */
00291                 q = p;
00292                 p = p->next;
00293                 TALLOC_FREE( q );
00294         }
00295 
00296         return NT_STATUS_OK;
00297 }
00298 

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