Print this page
    
NEX-14547 Get UNIX group info. from AD/LDAP with partial RFC2307 schema
NEX-13132 smbd dumping core in nss_ldap.so.1`getbymember
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libsldap/common/ns_connmgmt.h
          +++ new/usr/src/lib/libsldap/common/ns_connmgmt.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + *
       25 + * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  24   26   */
  25   27  
  26      -
  27   28  #ifndef _NS_CONNMGMT_H
  28   29  #define _NS_CONNMGMT_H
  29   30  
  30      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  31      -
  32   31  #ifdef __cplusplus
  33   32  extern "C" {
  34   33  #endif
  35   34  
  36   35  #include <thread.h>
  37   36  #include "ns_sldap.h"
  38   37  #include "ns_internal.h"
  39   38  #include "ns_cache_door.h"
  40   39  
  41   40  struct ns_conn_user; /* connection user, forward definition */
  42   41  struct ns_conn_mt;   /* multi-threaded (MT) connection, forward definition */
  43   42  struct ns_conn_mgmt; /* connection management, forward definition */
  44   43  
  45   44  #define NS_CONN_MT_USER_NO_MAX  -1
  46   45  #define NS_CONN_MT_USER_MAX     NS_CONN_MT_USER_NO_MAX
  47   46  #define NS_LIST_TRY_MAX         3
  48   47  
  49   48  /*
  50   49   * Structure for handling the waiter of a pending multi-threaded (MT) connection
  51   50   */
  52   51  typedef struct ns_conn_waiter {
  53   52          cond_t                  waitcv;
  54   53          uint8_t                 signaled;
  55   54          struct ns_conn_user     *key;
  56   55          struct ns_conn_waiter   *next, *prev;
  57   56  } ns_conn_waiter_t;
  58   57  
  59   58  /*
  60   59   * type of a connection user
  61   60   */
  62   61  typedef enum {
  63   62          NS_CONN_USER_SEARCH     = 1,
  64   63          NS_CONN_USER_WRITE      = 2,
  65   64          NS_CONN_USER_AUTH       = 3,
  66   65          NS_CONN_USER_GETENT     = 4
  67   66  } ns_conn_user_type_t;
  68   67  
  69   68  /*
  70   69   * state of a connection user
  71   70   */
  72   71  typedef enum {
  73   72          NS_CONN_USER_UNINITED           = 0,
  74   73          NS_CONN_USER_ALLOCATED          = 1,
  75   74          NS_CONN_USER_FINDING            = 2, /* looking for an MT connection */
  76   75          NS_CONN_USER_WAITING            = 3, /* waiting for an MT connection */
  77   76          NS_CONN_USER_WOKEUP             = 4,
  78   77          NS_CONN_USER_CONNECT_ERROR      = 5,
  79   78          NS_CONN_USER_CONNECTED          = 6,
  80   79          NS_CONN_USER_DISCONNECTED       = 7,
  81   80          NS_CONN_USER_FREED              = 8
  82   81  } ns_conn_user_state_t;
  83   82  
  84   83  /*
  85   84   * A connection user represents a request processed by libsldap. It
  86   85   * usually is a thread using the same connection from start to end.
  87   86   * Different connection users of the same type can share the same
  88   87   * connection opened for that type. But search and getent users can
  89   88   * share the same connection opened for either search or getent. AUTH
  90   89   * connection are not shareable.
  91   90   *
  92   91   * A getent user may have a longer lifespan and live outside of libsldap.
  93   92   * This is because the associated search cookie is passed back to the caller
  94   93   * via the firstEntry call and used in the subsequent nextEntry or endEntry
  95   94   * calls. Even though the firstEntry and the nextEntry/endEntry calls may
  96   95   * be running in a different thread, the connection being used will be the
  97   96   * same. It is the one assigend during the firstEntry call.
  98   97   */
  99   98  struct ns_conn_user {
 100   99          ns_conn_user_type_t     type; /* search, write, auth, getent, ... */
 101  100          ns_conn_user_state_t    state;
 102  101          thread_t                tid;   /* id of the thread starts the request */
 103  102          struct ns_conn_user     *next; /* next conn_user in the linked list */
 104  103          struct ns_conn_mt       *conn_mt; /* the MT connection being used */
 105  104          struct ns_conn_mgmt     *conn_mgmt; /* ref counted conn management */
 106  105          void                    *userinfo; /* private data of the request */
 107  106          ns_ldap_return_code     ns_rc; /* error return code */
 108  107          ns_ldap_error_t         *ns_error; /* error info */
 109  108          boolean_t               referral; /* using a referred server ? */
 110  109          boolean_t               retry; /* retry the request on certain error? */
 111  110          boolean_t               keep_conn; /* keep the conn for reuse ? */
 112  111          boolean_t               use_mt_conn; /* using/used an MT connection ? */
 113  112          boolean_t               bad_mt_conn; /* MT connection is not usable ? */
 114  113  };
 115  114  
 116  115  /*
 117  116   * state of an MT connection
 118  117   */
 119  118  typedef enum {
 120  119          NS_CONN_MT_UNINITED             = 0,
 121  120          NS_CONN_MT_CONNECTING           = 1,
 122  121          NS_CONN_MT_CONNECT_ERROR        = 2,
 123  122          NS_CONN_MT_CONNECTED            = 3,
 124  123          NS_CONN_MT_CLOSING              = 4
 125  124  } ns_conn_mt_state_t;
 126  125  
 127  126  /*
 128  127   * An ns_conn_mt (or MT connection) represents an ldap connection
 129  128   * that can be shared among multiple threads. It also represents
 130  129   * the set of connection users using the ldap connection. It contains
 131  130   * a pointer to the Connection structure that has the physical info
 132  131   * of the connection (server name, address, ldap handle, etc). It
 133  132   * also contains a linked list of all the conn_user using the ldap
 134  133   * connection. The connection users can wait on an MT connection
 135  134   * to become available or be told to abort and clean up when one of
 136  135   * the connection user detects an error and knows that the connection
 137  136   * is no longer usable. The error info is then saved in the structure
 138  137   * for other users to consume.
 139  138   *
 140  139   * An MT connection is meant to be shared concurrently and persistent.
 141  140   * Even when there's no current user, it will be kept by the connection
 142  141   * management, waiting for the next user. It will be closed when
 143  142   * a connection error is detected, when a better server should be
 144  143   * used, when the Native LDAP configuration change, or when the libsldap
 145  144   * is being unloaded.
 146  145   */
 147  146  typedef struct ns_conn_mt {
 148  147          mutex_t                 lock;
 149  148          ns_conn_mt_state_t      state;
 150  149          pid_t                   pid; /* process creates the connection */
 151  150          thread_t                tid; /* thread creates the connection */
 152  151          struct ns_conn_mt       *next; /* next conn_mt in the linked list */
 153  152          ns_conn_user_t          *cu_head; /* head of conn_user linked list */
 154  153          ns_conn_user_t          *cu_tail; /* tail of conn_user linked list */
 155  154          struct ns_conn_mgmt     *conn_mgmt; /* ref counted conn management */
 156  155          ns_conn_waiter_t        waiter; /* first of the connection waiters */
 157  156          uint_t                  cu_cnt; /* number of the using conn_user */
 158  157          int32_t                 cu_max; /* max. allowed number of conn_user */
 159  158          uint_t                  waiter_cnt; /* number of waiters */
 160  159          ns_conn_user_type_t     opened_for; /* type of conn_user opened for */
 161  160          Connection              *conn; /* name, IP address, ldap handle, etc */
 162  161          time_t                  create_time; /* time when connection created */
 163  162          time_t                  access_time; /* time when last used */
 164  163          ns_ldap_return_code     ns_rc; /* saved error code */
 165  164          ns_ldap_error_t         *ns_error; /* saved error info */
 166  165          boolean_t               close_when_nouser;  /* close connection when */
 167  166                                                      /* last user is done ? */
 168  167          boolean_t               detached; /* no longer in connection pool? */
 169  168          boolean_t               referral; /* using a referred server ? */
 170  169  } ns_conn_mt_t;
 171  170  
 172  171  /*
 173  172   * state of a connection management
 174  173   * (a connection pool sharing the same native LDAP configuration)
 175  174   */
 176  175  typedef enum {
 177  176          NS_CONN_MGMT_UNINITED   = 0,
 178  177          NS_CONN_MGMT_INACTIVE   = 1, /* conn sharing not yet requested */
 179  178          NS_CONN_MGMT_ACTIVE     = 2, /* connection sharing required/requested */
 180  179          NS_CONN_MGMT_DETACHED   = 3  /* on the way down, no new user allowed */
 181  180  } ns_conn_mgmt_state_t;
 182  181  
 183  182  /*
 184  183   * An ns_conn_mgmt (or connection management) represents the set of MT
 185  184   * connections using the same native LDAP configuration. It is a connection
 186  185   * pool that can adjust the MT connection status and usage based on the
 187  186   * change notifications it receives from the ldap_cachemgr daemon, OR When
 188  187   * the change is detected at config refresh time. When a server status
 189  188   * change (up or down) notification is received or detected, it will
 190  189   * close the MT connections using the server. Or mark them as to-be-closed
 191  190   * and close them when all users are done using them. When a config change
 192  191   * notice is received, it will detach itself and allow a new ns_conn_mgmt be
 193  192   * created for the new configuration. The old config would still be used
 194  193   * by the detached ns_conn_mgmt. Both will be destroyed when all existing
 195  194   * conn_user are done. Any conn_user and MT connection created after the
 196  195   * configuration switch will use the new configuration.
 197  196   *
 198  197   * Note that there's always just one current ns_conn_mgmt. Its usage is
 199  198   * reference counted. Any new conn_user or MT connection referencing
 200  199   * the ns_conn_mgmt adds 1 to the count, any release of the ns_conn_mgmt
 201  200   * decrement the count by 1. The ns_conn_mgmt can not be freed until
 202  201   * the reference count becomes zero.
 203  202   *
 204  203   * Each ns_conn_mgmt references a native LDAP configuration. The config
 205  204   * component of this library always maintains a global configuration. It is
 206  205   * referred to as the current global config. The current ns_conn_mgmt
 207  206   * uses that global config. When an ns_conn_mgmt is detached, or not
 208  207   * longer active/current, the config it uses is no longer the current global
 209  208   * one, which is referred as the per connection management config. When
 210  209   * the ns_conn_mgmt is freed, the config will also be destroyed.
 211  210   */
 212  211  
 213  212  typedef struct ns_conn_mgmt {
 214  213          mutex_t         lock;
 215  214          ns_conn_mgmt_state_t state;
 216  215          pid_t           pid; /* process creates the conn_mgmt */
 217  216          thread_t        procchg_tid; /* id of the change monitor thread */
 218  217          ns_conn_mt_t    *cm_head; /* head of the conn_mt linked list */
 219  218          ns_conn_mt_t    *cm_tail; /* tail of the conn_mt linked list */
 220  219          mutex_t         cfg_lock; /* lock serializes access to config */
 221  220          ldap_get_chg_cookie_t cfg_cookie; /* used to detect if config changes */
 222  221          ns_config_t     *config; /* the native LDAP config being used */
 223  222          char            **pservers; /* preferred servers defined in config */
 224  223          uint_t          cm_cnt;  /* number of MT connection in the pool */
 225  224          uint_t          ref_cnt; /* number of reference by conn_MT/conn_user */
 226  225          boolean_t       is_nscd; /* running in a nscd ? */
 227  226          boolean_t       is_peruser_nscd; /* running in a per-user nscd ? */
 228  227          boolean_t       ldap_mt; /* libldap supports multi-threaded client ? */
 229  228          boolean_t       do_mt_conn;     /* need and able to do MT conn ? */
 230  229          boolean_t       shutting_down;  /* on the way down ? */
 231  230          boolean_t       cfg_reloaded;   /* config is not current ? */
 232  231          boolean_t       procchg_started; /* change monitor thread started ? */
 233  232          boolean_t       procchg_door_call; /* in door call and waiting ? */
 234  233          boolean_t       pservers_loaded; /* pservers array is set ? */
 235  234  } ns_conn_mgmt_t;
 236  235  
 237  236  /*
 238  237   * For a connection management and the conn_mt connections it manages, it is
 239  238   * very helpful to know exactly when the Native LDAP configuration changes
 240  239   * and when the status of the configured servers change. If the config
 241  240   * changes, new connection management will be created. If servers go up
 242  241   * or down, conn_mt connections being used need to be dropped or switched.
 243  242   * For processes other than the main nscd, the changes has to be detected
 244  243   * in a less efficient way by libsldap. For the main nscd (not including
 245  244   * peruser nscd), the connection management which has active conn_mt
 246  245   * connections can rely on the ldap_cachemgr daemon to report if there's any
 247  246   * change in servers' status or if the native LDAP configuration has changed.
 248  247   *
 249  248   * The mechanism for reporting of the changes is a door call sent from
 250  249   * libsldap to ldap_cachemgr. The call will not be returned until changes
 251  250   * detected by ldap_cachemgr. When the change info is passed back to
 252  251   * libsldap, the change monitor thread will wake up from the door call
 253  252   * and process the notification. For servers went from up to down, the
 254  253   * associated MT connections will be closed, and then all conn_users'
 255  254   * state will be marked as closing. When a conn_user notices it, the
 256  255   * operations represented by that conn_user will be ended with error
 257  256   * info. When a more preferred server is up, MT connections using
 258  257   * less preferred servers will be marked as closed-when-all-user-done,
 259  258   * so that new connection will be opened and using the preferred server.
 260  259   * A configuration change causes the current connection management and
 261  260   * the configuration it uses to become detached but continually being
 262  261   * used by the old MT connections. Any new MT connection opened will
 263  262   * be put in a new connection management and uses the new configuration
 264  263   * immediately.
 265  264   */
 266  265  typedef enum {
 267  266          NS_SERVER_UP    = 1,
 268  267          NS_SERVER_DOWN  = 2
 269  268  } ns_server_status_t;
 270  269  
 271  270  typedef struct ns_server_status_change {
 272  271          int                     num_server;
 273  272          boolean_t               config_changed;
 274  273          ns_server_status_t      *changes;       /* array of status change */
 275  274          char                    **servers;      /* array of server */
 276  275  } ns_server_status_change_t;
 277  276  
 278  277  /*
 279  278   * connection management functions
 280  279   */
 281  280  ns_conn_mgmt_t *__s_api_conn_mgmt_init();
 282  281  int __s_api_setup_mt_ld(LDAP *ld);
 283  282  int __s_api_check_mtckey();
 284  283  void __s_api_use_prev_conn_mgmt(int, ns_config_t *);
 285  284  ns_conn_user_t *__s_api_conn_user_init(int, void *, boolean_t);
 286  285  void __s_api_conn_mt_return(ns_conn_user_t *);
 287  286  void __s_api_conn_user_free(ns_conn_user_t *);
 288  287  int __s_api_conn_mt_add(Connection *con, ns_conn_user_t *, ns_ldap_error_t **);
 289  288  int __s_api_conn_mt_get(const char *, const int, const ns_cred_t *,
 290  289          Connection **, ns_ldap_error_t **, ns_conn_user_t *);
 291  290  void __s_api_conn_mt_remove(ns_conn_user_t *, int, ns_ldap_error_t **);
 292  291  int __s_api_check_libldap_MT_conn_support(ns_conn_user_t *, LDAP *ld,
 293  292          ns_ldap_error_t **);
 294  293  void __s_api_conn_mt_close(ns_conn_user_t *, int, ns_ldap_error_t **);
 295  294  void __s_api_reinit_conn_mgmt_new_config(ns_config_t *);
 296  295  int __s_api_setup_retry_search(ns_conn_user_t **, ns_conn_user_type_t, int *,
 297  296          int *, ns_ldap_error_t **);
 298  297  int __s_api_setup_getnext(ns_conn_user_t *, int *, ns_ldap_error_t **);
 299  298  void __s_api_shutdown_conn_mgmt();
 300  299  
 301  300  #ifdef __cplusplus
 302  301  }
 303  302  #endif
 304  303  
 305  304  #endif /* _NS_CONNMGMT_H */
  
    | 
      ↓ open down ↓ | 
    264 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX