Home | History | Annotate | Line # | Download | only in rbac
      1  1.1  christos /*	$NetBSD: rbacuser.c,v 1.2 2021/08/14 16:14:53 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /* rbacuser.c - RBAC users */
      4  1.1  christos /* $OpenLDAP$ */
      5  1.1  christos /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6  1.1  christos  *
      7  1.1  christos  *
      8  1.1  christos  * All rights reserved.
      9  1.1  christos  *
     10  1.1  christos  * Redistribution and use in source and binary forms, with or without
     11  1.1  christos  * modification, are permitted only as authorized by the OpenLDAP
     12  1.1  christos  * Public License.
     13  1.1  christos  *
     14  1.1  christos  * A copy of this license is available in the file LICENSE in the
     15  1.1  christos  * top-level directory of the distribution or, alternatively, at
     16  1.1  christos  * <http://www.OpenLDAP.org/license.html>.
     17  1.1  christos  */
     18  1.1  christos /* ACKNOWLEDGEMENTS:
     19  1.1  christos  */
     20  1.1  christos 
     21  1.1  christos #include <sys/cdefs.h>
     22  1.1  christos __RCSID("$NetBSD: rbacuser.c,v 1.2 2021/08/14 16:14:53 christos Exp $");
     23  1.1  christos 
     24  1.1  christos #include "portable.h"
     25  1.1  christos 
     26  1.1  christos #include <stdio.h>
     27  1.1  christos 
     28  1.1  christos #include <ac/string.h>
     29  1.1  christos 
     30  1.1  christos #include "slap.h"
     31  1.1  christos #include "slap-config.h"
     32  1.1  christos #include "lutil.h"
     33  1.1  christos 
     34  1.1  christos #include "rbac.h"
     35  1.1  christos 
     36  1.1  christos static int ppolicy_cid = -1;
     37  1.1  christos 
     38  1.1  christos static rbac_user_t *
     39  1.1  christos rbac_alloc_user()
     40  1.1  christos {
     41  1.1  christos 	rbac_user_t *userp = ch_calloc( 1, sizeof(rbac_user_t) );
     42  1.1  christos 
     43  1.1  christos 	BER_BVZERO( &userp->tenantid );
     44  1.1  christos 	BER_BVZERO( &userp->uid );
     45  1.1  christos 	BER_BVZERO( &userp->dn );
     46  1.1  christos 	BER_BVZERO( &userp->password );
     47  1.1  christos 	BER_BVZERO( &userp->constraints );
     48  1.1  christos 	BER_BVZERO( &userp->msg );
     49  1.1  christos 	userp->roles = NULL;
     50  1.1  christos 	userp->role_constraints = NULL;
     51  1.1  christos 
     52  1.1  christos 	return userp;
     53  1.1  christos }
     54  1.1  christos 
     55  1.1  christos static int
     56  1.1  christos rbac_read_user_cb( Operation *op, SlapReply *rs )
     57  1.1  christos {
     58  1.1  christos 	rbac_callback_info_t *cbp = op->o_callback->sc_private;
     59  1.1  christos 	rbac_ad_t *user_ads;
     60  1.1  christos 	rbac_user_t *userp = NULL;
     61  1.1  christos 	int rc = 0, i;
     62  1.1  christos 
     63  1.1  christos 	Debug( LDAP_DEBUG_ANY, "rbac_read_user_cb\n" );
     64  1.1  christos 
     65  1.1  christos 	if ( rs->sr_type != REP_SEARCH ) {
     66  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_read_user_cb: "
     67  1.1  christos 				"sr_type != REP_SEARCH\n" );
     68  1.1  christos 		return 0;
     69  1.1  christos 	}
     70  1.1  christos 
     71  1.1  christos 	assert( cbp );
     72  1.1  christos 
     73  1.1  christos 	user_ads = cbp->tenantp->schema->user_ads;
     74  1.1  christos 
     75  1.1  christos 	userp = rbac_alloc_user();
     76  1.1  christos 	if ( !userp ) {
     77  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_read_user_cb: "
     78  1.1  christos 				"rbac_alloc_user failed\n" );
     79  1.1  christos 
     80  1.1  christos 		goto done;
     81  1.1  christos 	}
     82  1.1  christos 
     83  1.1  christos 	ber_dupbv( &userp->dn, &rs->sr_entry->e_name );
     84  1.1  christos 
     85  1.1  christos 	Debug( LDAP_DEBUG_ANY, "DEBUG rbac_read_user_cb (%s): "
     86  1.1  christos 			"rc (%d)\n",
     87  1.1  christos 			userp->dn.bv_val, rc );
     88  1.1  christos 
     89  1.1  christos 	for ( i = 0; !BER_BVISNULL( &user_ads[i].attr ); i++ ) {
     90  1.1  christos 		Attribute *attr = NULL;
     91  1.1  christos 
     92  1.1  christos 		attr = attr_find( rs->sr_entry->e_attrs, *user_ads[i].ad );
     93  1.1  christos 		if ( attr != NULL ) {
     94  1.1  christos 			switch ( user_ads[i].type ) {
     95  1.1  christos 				case RBAC_ROLE_ASSIGNMENT:
     96  1.1  christos 					ber_bvarray_dup_x( &userp->roles, attr->a_nvals, NULL );
     97  1.1  christos 					break;
     98  1.1  christos 				case RBAC_ROLE_CONSTRAINTS:
     99  1.1  christos 					ber_bvarray_dup_x(
    100  1.1  christos 							&userp->role_constraints, attr->a_nvals, NULL );
    101  1.1  christos 					break;
    102  1.1  christos 				case RBAC_USER_CONSTRAINTS:
    103  1.1  christos 					ber_dupbv_x( &userp->constraints, &attr->a_nvals[0], NULL );
    104  1.1  christos 					break;
    105  1.1  christos 				case RBAC_UID:
    106  1.1  christos 					ber_dupbv_x( &userp->uid, &attr->a_nvals[0], NULL );
    107  1.1  christos 					break;
    108  1.1  christos 				default:
    109  1.1  christos 					break;
    110  1.1  christos 			}
    111  1.1  christos 		}
    112  1.1  christos 	}
    113  1.1  christos 
    114  1.1  christos done:;
    115  1.1  christos 	cbp->private = userp;
    116  1.1  christos 
    117  1.1  christos 	return 0;
    118  1.1  christos }
    119  1.1  christos 
    120  1.1  christos static int
    121  1.1  christos rbac_bind_cb( Operation *op, SlapReply *rs )
    122  1.1  christos {
    123  1.1  christos 	rbac_user_t *ui = op->o_callback->sc_private;
    124  1.1  christos 
    125  1.1  christos 	LDAPControl *ctrl = ldap_control_find(
    126  1.1  christos 			LDAP_CONTROL_PASSWORDPOLICYRESPONSE, rs->sr_ctrls, NULL );
    127  1.1  christos 	if ( ctrl ) {
    128  1.1  christos 		LDAP *ld;
    129  1.1  christos 		ber_int_t expire, grace;
    130  1.1  christos 		LDAPPasswordPolicyError error;
    131  1.1  christos 
    132  1.1  christos 		ldap_create( &ld );
    133  1.1  christos 		if ( ld ) {
    134  1.1  christos 			int rc = ldap_parse_passwordpolicy_control(
    135  1.1  christos 					ld, ctrl, &expire, &grace, &error );
    136  1.1  christos 			if ( rc == LDAP_SUCCESS ) {
    137  1.1  christos 				ui->authz = RBAC_PASSWORD_GOOD;
    138  1.1  christos 				if ( grace > 0 ) {
    139  1.1  christos 					//ui->msg.bv_len = sprintf(ui->msg.bv_val,
    140  1.1  christos 					//		"Password expired; %d grace logins remaining",
    141  1.1  christos 					//		grace);
    142  1.1  christos 					ui->authz = RBAC_BIND_NEW_AUTHTOK_REQD;
    143  1.1  christos 				} else if ( error != PP_noError ) {
    144  1.1  christos 					ber_str2bv( ldap_passwordpolicy_err2txt( error ), 0, 0,
    145  1.1  christos 							&ui->msg );
    146  1.1  christos 
    147  1.1  christos 					switch ( error ) {
    148  1.1  christos 						case PP_passwordExpired:
    149  1.1  christos 							ui->authz = RBAC_PASSWORD_EXPIRATION_WARNING;
    150  1.1  christos 
    151  1.1  christos 							if ( expire >= 0 ) {
    152  1.1  christos 								char *unit = "seconds";
    153  1.1  christos 								if ( expire > 60 ) {
    154  1.1  christos 									expire /= 60;
    155  1.1  christos 									unit = "minutes";
    156  1.1  christos 								}
    157  1.1  christos 								if ( expire > 60 ) {
    158  1.1  christos 									expire /= 60;
    159  1.1  christos 									unit = "hours";
    160  1.1  christos 								}
    161  1.1  christos 								if ( expire > 24 ) {
    162  1.1  christos 									expire /= 24;
    163  1.1  christos 									unit = "days";
    164  1.1  christos 								}
    165  1.1  christos #if 0 /* Who warns about expiration so far in advance? */
    166  1.1  christos 								if (expire > 7) {
    167  1.1  christos 									expire /= 7;
    168  1.1  christos 									unit = "weeks";
    169  1.1  christos 								}
    170  1.1  christos 								if (expire > 4) {
    171  1.1  christos 									expire /= 4;
    172  1.1  christos 									unit = "months";
    173  1.1  christos 								}
    174  1.1  christos 								if (expire > 12) {
    175  1.1  christos 									expire /= 12;
    176  1.1  christos 									unit = "years";
    177  1.1  christos 								}
    178  1.1  christos #endif
    179  1.1  christos 							}
    180  1.1  christos 
    181  1.1  christos 							//rs->sr_err = ;
    182  1.1  christos 							break;
    183  1.1  christos 						case PP_accountLocked:
    184  1.1  christos 							ui->authz = RBAC_ACCOUNT_LOCKED;
    185  1.1  christos 							//rs->sr_err = ;
    186  1.1  christos 							break;
    187  1.1  christos 						case PP_changeAfterReset:
    188  1.1  christos 							ui->authz = RBAC_CHANGE_AFTER_RESET;
    189  1.1  christos 							rs->sr_err = LDAP_SUCCESS;
    190  1.1  christos 							break;
    191  1.1  christos 						case PP_passwordModNotAllowed:
    192  1.1  christos 							ui->authz = RBAC_NO_MODIFICATIONS;
    193  1.1  christos 							//rs->sr_err = ;
    194  1.1  christos 							break;
    195  1.1  christos 						case PP_mustSupplyOldPassword:
    196  1.1  christos 							ui->authz = RBAC_MUST_SUPPLY_OLD;
    197  1.1  christos 							//rs->sr_err = ;
    198  1.1  christos 							break;
    199  1.1  christos 						case PP_insufficientPasswordQuality:
    200  1.1  christos 							ui->authz = RBAC_INSUFFICIENT_QUALITY;
    201  1.1  christos 							//rs->sr_err = ;
    202  1.1  christos 							break;
    203  1.1  christos 						case PP_passwordTooShort:
    204  1.1  christos 							ui->authz = RBAC_PASSWORD_TOO_SHORT;
    205  1.1  christos 							//rs->sr_err = ;
    206  1.1  christos 							break;
    207  1.1  christos 						case PP_passwordTooYoung:
    208  1.1  christos 							ui->authz = RBAC_PASSWORD_TOO_YOUNG;
    209  1.1  christos 							//rs->sr_err = ;
    210  1.1  christos 							break;
    211  1.1  christos 						case PP_passwordInHistory:
    212  1.1  christos 							ui->authz = RBAC_HISTORY_VIOLATION;
    213  1.1  christos 							//rs->sr_err = ;
    214  1.1  christos 							break;
    215  1.1  christos 						case PP_noError:
    216  1.1  christos 						default:
    217  1.1  christos 							// do nothing
    218  1.1  christos 							//ui->authz = RBAC_PASSWORD_GOOD;
    219  1.1  christos 							rs->sr_err = LDAP_SUCCESS;
    220  1.1  christos 							break;
    221  1.1  christos 					}
    222  1.1  christos 
    223  1.1  christos //					switch (error) {
    224  1.1  christos //					case PP_passwordExpired:
    225  1.1  christos 						/* report this during authz */
    226  1.1  christos //						rs->sr_err = LDAP_SUCCESS;
    227  1.1  christos 						/* fallthru */
    228  1.1  christos //					case PP_changeAfterReset:
    229  1.1  christos //						ui->authz = RBAC_BIND_NEW_AUTHTOK_REQD;
    230  1.1  christos //					}
    231  1.1  christos 				}
    232  1.1  christos 			}
    233  1.1  christos 			ldap_unbind_ext( ld, NULL, NULL );
    234  1.1  christos 		}
    235  1.1  christos 	}
    236  1.1  christos 
    237  1.1  christos 	return 0;
    238  1.1  christos }
    239  1.1  christos 
    240  1.1  christos /* exported user functions */
    241  1.1  christos int
    242  1.1  christos rbac_authenticate_user( Operation *op, rbac_user_t *userp )
    243  1.1  christos {
    244  1.1  christos 	int rc = LDAP_SUCCESS;
    245  1.1  christos 	slap_callback cb = { 0 };
    246  1.1  christos 	SlapReply rs2 = { REP_RESULT };
    247  1.1  christos 	Operation op2 = *op;
    248  1.1  christos 	LDAPControl *sctrls[4];
    249  1.1  christos 	LDAPControl sctrl[3];
    250  1.1  christos 	int nsctrls = 0;
    251  1.1  christos 	LDAPControl c;
    252  1.1  christos 	struct berval ber_bvnull = BER_BVNULL;
    253  1.1  christos 	struct berval dn, ndn;
    254  1.1  christos 
    255  1.1  christos 	rc = dnPrettyNormal( 0, &userp->dn, &dn, &ndn, NULL );
    256  1.1  christos 	if ( rc != LDAP_SUCCESS ) {
    257  1.1  christos 		goto done;
    258  1.1  christos 	}
    259  1.1  christos 
    260  1.1  christos 	cb.sc_response = rbac_bind_cb;
    261  1.1  christos 	cb.sc_private = userp;
    262  1.1  christos 	op2.o_callback = &cb;
    263  1.1  christos 	op2.o_dn = ber_bvnull;
    264  1.1  christos 	op2.o_ndn = ber_bvnull;
    265  1.1  christos 	op2.o_tag = LDAP_REQ_BIND;
    266  1.1  christos 	op2.o_protocol = LDAP_VERSION3;
    267  1.1  christos 	op2.orb_method = LDAP_AUTH_SIMPLE;
    268  1.1  christos 	op2.orb_cred = userp->password;
    269  1.1  christos 	op2.o_req_dn = dn;
    270  1.1  christos 	op2.o_req_ndn = ndn;
    271  1.1  christos 
    272  1.1  christos 	// loading the ldap pw policy controls loaded into here, added by smm:
    273  1.1  christos 	c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST;
    274  1.1  christos 	c.ldctl_value.bv_val = NULL;
    275  1.1  christos 	c.ldctl_value.bv_len = 0;
    276  1.1  christos 	c.ldctl_iscritical = 0;
    277  1.1  christos 	sctrl[nsctrls] = c;
    278  1.1  christos 	sctrls[nsctrls] = &sctrl[nsctrls];
    279  1.1  christos 	sctrls[++nsctrls] = NULL;
    280  1.1  christos 	op2.o_ctrls = sctrls;
    281  1.1  christos 
    282  1.1  christos 	if ( ppolicy_cid < 0 ) {
    283  1.1  christos 		rc = slap_find_control_id( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
    284  1.1  christos 				&ppolicy_cid );
    285  1.1  christos 		if ( rc != LDAP_SUCCESS ) {
    286  1.1  christos 			goto done;
    287  1.1  christos 		}
    288  1.1  christos 	}
    289  1.1  christos 	// smm - need to set the control flag too:
    290  1.1  christos 	op2.o_ctrlflag[ppolicy_cid] = SLAP_CONTROL_CRITICAL;
    291  1.1  christos 
    292  1.1  christos 	slap_op_time( &op2.o_time, &op2.o_tincr );
    293  1.1  christos 	op2.o_bd = frontendDB;
    294  1.1  christos 	rc = op2.o_bd->be_bind( &op2, &rs2 );
    295  1.1  christos 	if ( userp->authz > 0 ) {
    296  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_authenticate_user (%s): "
    297  1.1  christos 				"password policy violation (%d)\n",
    298  1.1  christos 				userp->dn.bv_val ? userp->dn.bv_val : "NULL", userp->authz );
    299  1.1  christos 	}
    300  1.1  christos 
    301  1.1  christos done:;
    302  1.1  christos 	ch_free( dn.bv_val );
    303  1.1  christos 	ch_free( ndn.bv_val );
    304  1.1  christos 
    305  1.1  christos 	Debug( LDAP_DEBUG_ANY, "rbac_authenticate_user (%s): "
    306  1.1  christos 			"rc (%d)\n",
    307  1.1  christos 			userp->dn.bv_val ? userp->dn.bv_val : "NULL", rc );
    308  1.1  christos 	return rc;
    309  1.1  christos }
    310  1.1  christos 
    311  1.1  christos /*
    312  1.1  christos 	isvalidusername(): from OpenLDAP ~/contrib/slapd-modules/nssov/passwd.c
    313  1.1  christos 	Checks to see if the specified name is a valid user name.
    314  1.1  christos 
    315  1.1  christos     This test is based on the definition from POSIX (IEEE Std 1003.1, 2004, 3.426 User Name
    316  1.1  christos 	 and 3.276 Portable Filename Character Set):
    317  1.1  christos 	 http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_426
    318  1.1  christos 	 http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_276
    319  1.1  christos 
    320  1.1  christos 	 The standard defines user names valid if they contain characters from
    321  1.1  christos 	 the set [A-Za-z0-9._-] where the hyphen should not be used as first
    322  1.1  christos 	 character. As an extension this test allows the dolar '$' sign as the last
    323  1.1  christos 	 character to support Samba special accounts.
    324  1.1  christos */
    325  1.1  christos static int
    326  1.1  christos isvalidusername( struct berval *bv )
    327  1.1  christos {
    328  1.1  christos 	int i;
    329  1.1  christos 	char *name = bv->bv_val;
    330  1.1  christos 	if ( (name == NULL) || ( name[0] == '\0' ) ) return 0;
    331  1.1  christos 	/* check first character */
    332  1.1  christos 	if ( !( ( name[0] >= 'A' && name[0] <= 'Z' ) ||
    333  1.1  christos 				 ( name[0] >= 'a' && name[0] <= 'z' ) ||
    334  1.1  christos 				 ( name[0] >= '0' && name[0] <= '9' ) || name[0] == '.' ||
    335  1.1  christos 				 name[0] == '_' ) )
    336  1.1  christos 		return 0;
    337  1.1  christos 	/* check other characters */
    338  1.1  christos 	for ( i = 1; i < bv->bv_len; i++ ) {
    339  1.1  christos 		if ( name[i] == '$' ) {
    340  1.1  christos 			/* if the char is $ we require it to be the last char */
    341  1.1  christos 			if ( name[i + 1] != '\0' ) return 0;
    342  1.1  christos 		} else if ( !( ( name[i] >= 'A' && name[i] <= 'Z' ) ||
    343  1.1  christos 							( name[i] >= 'a' && name[i] <= 'z' ) ||
    344  1.1  christos 							( name[i] >= '0' && name[i] <= '9' ) ||
    345  1.1  christos 							name[i] == '.' || name[i] == '_' ||
    346  1.1  christos 							name[i] == '-' ) )
    347  1.1  christos 			return 0;
    348  1.1  christos 	}
    349  1.1  christos 	/* no test failed so it must be good */
    350  1.1  christos 	return -1;
    351  1.1  christos }
    352  1.1  christos 
    353  1.1  christos rbac_user_t *
    354  1.1  christos rbac_read_user( Operation *op, rbac_req_t *reqp )
    355  1.1  christos {
    356  1.1  christos 	int rc = LDAP_SUCCESS;
    357  1.1  christos 	tenant_info_t *tenantp = rbac_tid2tenant( &reqp->tenantid );
    358  1.1  christos 	rbac_user_t *userp = NULL;
    359  1.1  christos 	char fbuf[RBAC_BUFLEN];
    360  1.1  christos 	struct berval filter = { sizeof(fbuf), fbuf };
    361  1.1  christos 	SlapReply rs2 = { REP_RESULT };
    362  1.1  christos 	Operation op2 = *op;
    363  1.1  christos 	slap_callback cb = { 0 };
    364  1.1  christos 	rbac_callback_info_t rbac_cb;
    365  1.1  christos 
    366  1.1  christos 	if ( !tenantp ) {
    367  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_read_user: "
    368  1.1  christos 				"missing tenant information\n" );
    369  1.1  christos 		rc = LDAP_UNWILLING_TO_PERFORM;
    370  1.1  christos 		goto done;
    371  1.1  christos 	}
    372  1.1  christos 
    373  1.1  christos 	/* uid is a pre-requisite for reading the user information */
    374  1.1  christos 	if ( BER_BVISNULL( &reqp->uid ) ) {
    375  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_read_user: "
    376  1.1  christos 				"missing uid, unable to read user entry\n" );
    377  1.1  christos 		rc = LDAP_UNWILLING_TO_PERFORM;
    378  1.1  christos 		goto done;
    379  1.1  christos 	}
    380  1.1  christos 
    381  1.1  christos 	if ( !isvalidusername( &reqp->uid ) ) {
    382  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_read_user: "
    383  1.1  christos 				"invalid user id\n" );
    384  1.1  christos 		rc = LDAP_NO_SUCH_OBJECT;
    385  1.1  christos 		goto done;
    386  1.1  christos 	}
    387  1.1  christos 
    388  1.1  christos 	rbac_cb.tenantp = tenantp;
    389  1.1  christos 	rbac_cb.private = NULL;
    390  1.1  christos 
    391  1.1  christos 	memset( fbuf, 0, sizeof(fbuf) );
    392  1.1  christos 	strcpy( fbuf, "uid=" );
    393  1.1  christos 	strncat( fbuf, reqp->uid.bv_val, reqp->uid.bv_len );
    394  1.1  christos 	filter.bv_val = fbuf;
    395  1.1  christos 	filter.bv_len = strlen( fbuf );
    396  1.1  christos 
    397  1.1  christos 	if ( rc != LDAP_SUCCESS ) {
    398  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_create_session: "
    399  1.1  christos 				"invalid DN syntax\n" );
    400  1.1  christos 		goto done;
    401  1.1  christos 	}
    402  1.1  christos 
    403  1.1  christos 	cb.sc_private = &rbac_cb;
    404  1.1  christos 	cb.sc_response = rbac_read_user_cb;
    405  1.1  christos 	op2.o_callback = &cb;
    406  1.1  christos 	op2.o_tag = LDAP_REQ_SEARCH;
    407  1.1  christos 	op2.o_dn = tenantp->admin;
    408  1.1  christos 	op2.o_ndn = tenantp->admin;
    409  1.1  christos 	op2.o_req_dn = tenantp->users_basedn;
    410  1.1  christos 	op2.o_req_ndn = tenantp->users_basedn;
    411  1.1  christos 	op2.ors_filterstr = filter;
    412  1.1  christos 	op2.ors_filter = str2filter_x( &op2, filter.bv_val );
    413  1.1  christos 	op2.ors_scope = LDAP_SCOPE_SUBTREE;
    414  1.1  christos 	op2.ors_attrs = tenantp->schema->user_attrs;
    415  1.1  christos 	op2.ors_tlimit = SLAP_NO_LIMIT;
    416  1.1  christos 	op2.ors_slimit = SLAP_NO_LIMIT;
    417  1.1  christos 	op2.ors_attrsonly = 0;
    418  1.1  christos 	op2.o_bd = frontendDB;
    419  1.1  christos 	op2.ors_limit = NULL;
    420  1.1  christos 	rc = op2.o_bd->be_search( &op2, &rs2 );
    421  1.1  christos 	filter_free_x( &op2, op2.ors_filter, 1 );
    422  1.1  christos 
    423  1.1  christos done:;
    424  1.1  christos 	if ( rc == LDAP_SUCCESS && rbac_cb.private ) {
    425  1.1  christos 		userp = (rbac_user_t *)rbac_cb.private;
    426  1.1  christos 		if ( !BER_BVISNULL( &reqp->authtok ) )
    427  1.1  christos 			ber_dupbv( &userp->password, &reqp->authtok );
    428  1.1  christos 		rbac_cb.private = NULL;
    429  1.1  christos 		return userp;
    430  1.1  christos 	} else {
    431  1.1  christos 		userp = (rbac_user_t *)rbac_cb.private;
    432  1.1  christos 		rbac_free_user( userp );
    433  1.1  christos 		return NULL;
    434  1.1  christos 	}
    435  1.1  christos }
    436  1.1  christos 
    437  1.1  christos /* evaluate temporal constraints for the user */
    438  1.1  christos int
    439  1.1  christos rbac_user_temporal_constraint( rbac_user_t *userp )
    440  1.1  christos {
    441  1.1  christos 	int rc = LDAP_SUCCESS;
    442  1.1  christos 	rbac_constraint_t *cp = NULL;
    443  1.1  christos 
    444  1.1  christos 	if ( BER_BVISNULL( &userp->constraints ) ) {
    445  1.1  christos 		/* no temporal constraint */
    446  1.1  christos 		goto done;
    447  1.1  christos 	}
    448  1.1  christos 
    449  1.1  christos 	cp = rbac_bv2constraint( &userp->constraints );
    450  1.1  christos 	if ( !cp ) {
    451  1.1  christos 		Debug( LDAP_DEBUG_ANY, "rbac_user_temporal_constraint: "
    452  1.1  christos 				"invalid user constraint \n" );
    453  1.1  christos 		rc = LDAP_OTHER;
    454  1.1  christos 		goto done;
    455  1.1  christos 	}
    456  1.1  christos 
    457  1.1  christos 	rc = rbac_check_time_constraint( cp );
    458  1.1  christos 
    459  1.1  christos done:;
    460  1.1  christos 	rbac_free_constraint( cp );
    461  1.1  christos 
    462  1.1  christos 	return rc;
    463  1.1  christos }
    464  1.1  christos 
    465  1.1  christos /*
    466  1.1  christos rbac_constraint_t *
    467  1.1  christos rbac_user_role_constraintsx(rbac_user_t *userp)
    468  1.1  christos {
    469  1.1  christos 	rbac_constraint_t *tmp, *cp = NULL;
    470  1.1  christos 	int i = 0;
    471  1.1  christos 
    472  1.1  christos 	if (!userp || !userp->role_constraints)
    473  1.1  christos 		goto done;
    474  1.1  christos 
    475  1.1  christos 	while (!BER_BVISNULL(&userp->role_constraints[i])) {
    476  1.1  christos 		tmp = rbac_bv2constraint(&userp->role_constraints[i++]);
    477  1.1  christos 		if (tmp) {
    478  1.1  christos 			if (!cp) {
    479  1.1  christos 				cp = tmp;
    480  1.1  christos 			} else {
    481  1.1  christos 				tmp->next = cp;
    482  1.1  christos 				cp = tmp;
    483  1.1  christos 			}
    484  1.1  christos 		}
    485  1.1  christos 	}
    486  1.1  christos 
    487  1.1  christos done:;
    488  1.1  christos 	return cp;
    489  1.1  christos }
    490  1.1  christos */
    491  1.1  christos 
    492  1.1  christos rbac_constraint_t *
    493  1.1  christos rbac_user_role_constraints( BerVarray values )
    494  1.1  christos {
    495  1.1  christos 	rbac_constraint_t *curr, *head = NULL;
    496  1.1  christos 	int i = 0;
    497  1.1  christos 
    498  1.1  christos 	if ( values ) {
    499  1.1  christos 		while ( !BER_BVISNULL( &values[i] ) ) {
    500  1.1  christos 			curr = rbac_bv2constraint( &values[i++] );
    501  1.1  christos 			if ( curr ) {
    502  1.1  christos 				curr->next = head;
    503  1.1  christos 				head = curr;
    504  1.1  christos 			}
    505  1.1  christos 		}
    506  1.1  christos 	}
    507  1.1  christos 
    508  1.1  christos 	return head;
    509  1.1  christos }
    510  1.1  christos 
    511  1.1  christos /*
    512  1.1  christos 
    513  1.1  christos void main() {
    514  1.1  christos    item * curr, * head;
    515  1.1  christos    int i;
    516  1.1  christos 
    517  1.1  christos    head = NULL;
    518  1.1  christos 
    519  1.1  christos    for(i=1;i<=10;i++) {
    520  1.1  christos       curr = (item *)malloc(sizeof(item));
    521  1.1  christos       curr->val = i;
    522  1.1  christos       curr->next  = head;
    523  1.1  christos       head = curr;
    524  1.1  christos    }
    525  1.1  christos 
    526  1.1  christos    curr = head;
    527  1.1  christos 
    528  1.1  christos    while(curr) {
    529  1.1  christos       printf("%d\n", curr->val);
    530  1.1  christos       curr = curr->next ;
    531  1.1  christos    }
    532  1.1  christos }
    533  1.1  christos 
    534  1.1  christos  */
    535  1.1  christos 
    536  1.1  christos /*
    537  1.1  christos  *
    538  1.1  christos rbac_user_role_constraints2(BerVarray values)
    539  1.1  christos {
    540  1.1  christos 	rbac_constraint_t *tmp, *cp = NULL;
    541  1.1  christos 	int i = 0;
    542  1.1  christos 
    543  1.1  christos 	if (!values)
    544  1.1  christos 		goto done;
    545  1.1  christos 
    546  1.1  christos 	while (!BER_BVISNULL(&values[i])) {
    547  1.1  christos 		tmp = rbac_bv2constraint(&values[i++]);
    548  1.1  christos 		if (tmp) {
    549  1.1  christos 			if (!cp) {
    550  1.1  christos 				cp = tmp;
    551  1.1  christos 			} else {
    552  1.1  christos 				tmp->next = cp;
    553  1.1  christos 				cp = tmp;
    554  1.1  christos 				//cp->next = tmp;
    555  1.1  christos 				//cp = tmp->next;
    556  1.1  christos 
    557  1.1  christos 			}
    558  1.1  christos 		}
    559  1.1  christos 	}
    560  1.1  christos 
    561  1.1  christos done:;
    562  1.1  christos 	return cp;
    563  1.1  christos }
    564  1.1  christos 
    565  1.1  christos 
    566  1.1  christos rbac_user_role_constraints3(rbac_constraint_t *values)
    567  1.1  christos {
    568  1.1  christos 	rbac_constraint_t *tmp, *cp = NULL;
    569  1.1  christos 	int i = 0;
    570  1.1  christos 
    571  1.1  christos 	if (!values)
    572  1.1  christos 		goto done;
    573  1.1  christos 
    574  1.1  christos 	while (!BER_BVISNULL(values[i])) {
    575  1.1  christos 		tmp = rbac_bv2constraint(&values[i++]);
    576  1.1  christos 		if (tmp) {
    577  1.1  christos 			if (!cp) {
    578  1.1  christos 				cp = tmp;
    579  1.1  christos 			} else {
    580  1.1  christos 				tmp->next = cp;
    581  1.1  christos 				cp = tmp;
    582  1.1  christos 			}
    583  1.1  christos 		}
    584  1.1  christos 	}
    585  1.1  christos 
    586  1.1  christos done:;
    587  1.1  christos 	return cp;
    588  1.1  christos }
    589  1.1  christos */
    590  1.1  christos 
    591  1.1  christos void
    592  1.1  christos rbac_free_user( rbac_user_t *userp )
    593  1.1  christos {
    594  1.1  christos 	if ( !userp ) return;
    595  1.1  christos 
    596  1.1  christos 	if ( !BER_BVISNULL( &userp->tenantid ) ) {
    597  1.1  christos 		ber_memfree( userp->tenantid.bv_val );
    598  1.1  christos 	}
    599  1.1  christos 
    600  1.1  christos 	if ( !BER_BVISNULL( &userp->uid ) ) {
    601  1.1  christos 		ber_memfree( userp->uid.bv_val );
    602  1.1  christos 	}
    603  1.1  christos 
    604  1.1  christos 	if ( !BER_BVISNULL( &userp->dn ) ) {
    605  1.1  christos 		ber_memfree( userp->dn.bv_val );
    606  1.1  christos 	}
    607  1.1  christos 
    608  1.1  christos 	if ( !BER_BVISNULL( &userp->constraints ) ) {
    609  1.1  christos 		ber_memfree( userp->constraints.bv_val );
    610  1.1  christos 	}
    611  1.1  christos 
    612  1.1  christos 	if ( !BER_BVISNULL( &userp->password ) ) {
    613  1.1  christos 		ber_memfree( userp->password.bv_val );
    614  1.1  christos 	}
    615  1.1  christos 
    616  1.1  christos 	if ( !BER_BVISNULL( &userp->msg ) ) {
    617  1.1  christos 		ber_memfree( userp->msg.bv_val );
    618  1.1  christos 	}
    619  1.1  christos 
    620  1.1  christos 	if ( userp->roles ) ber_bvarray_free( userp->roles );
    621  1.1  christos 
    622  1.1  christos 	if ( userp->role_constraints ) ber_bvarray_free( userp->role_constraints );
    623  1.1  christos 
    624  1.1  christos 	ch_free( userp );
    625  1.1  christos }
    626