Home | History | Annotate | Line # | Download | only in nssov
      1  1.3  christos /*	$NetBSD: passwd.c,v 1.4 2025/09/05 21:16:17 christos Exp $	*/
      2  1.2  christos 
      3  1.1     lukem /* passwd.c - password lookup routines */
      4  1.2  christos /* $OpenLDAP$ */
      5  1.2  christos /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6  1.2  christos  *
      7  1.4  christos  * Copyright 2008-2024 The OpenLDAP Foundation.
      8  1.2  christos  * Portions Copyright 2008 by Howard Chu, Symas Corp.
      9  1.1     lukem  * All rights reserved.
     10  1.1     lukem  *
     11  1.1     lukem  * Redistribution and use in source and binary forms, with or without
     12  1.1     lukem  * modification, are permitted only as authorized by the OpenLDAP
     13  1.1     lukem  * Public License.
     14  1.1     lukem  *
     15  1.1     lukem  * A copy of this license is available in the file LICENSE in the
     16  1.1     lukem  * top-level directory of the distribution or, alternatively, at
     17  1.1     lukem  * <http://www.OpenLDAP.org/license.html>.
     18  1.1     lukem  */
     19  1.2  christos /* ACKNOWLEDGEMENTS:
     20  1.1     lukem  * This code references portions of the nss-ldapd package
     21  1.1     lukem  * written by Arthur de Jong. The nss-ldapd code was forked
     22  1.1     lukem  * from the nss-ldap library written by Luke Howard.
     23  1.1     lukem  */
     24  1.1     lukem 
     25  1.1     lukem #include "nssov.h"
     26  1.1     lukem 
     27  1.1     lukem /* ( nisSchema.2.0 NAME 'posixAccount' SUP top AUXILIARY
     28  1.1     lukem  *	 DESC 'Abstraction of an account with POSIX attributes'
     29  1.1     lukem  *	 MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
     30  1.1     lukem  *	 MAY ( userPassword $ loginShell $ gecos $ description ) )
     31  1.1     lukem  */
     32  1.1     lukem 
     33  1.1     lukem /* the basic search filter for searches */
     34  1.1     lukem static struct berval passwd_filter = BER_BVC("(objectClass=posixAccount)");
     35  1.1     lukem 
     36  1.1     lukem /* the attributes used in searches */
     37  1.1     lukem static struct berval passwd_keys[] = {
     38  1.1     lukem 	BER_BVC("uid"),
     39  1.1     lukem 	BER_BVC("userPassword"),
     40  1.1     lukem 	BER_BVC("uidNumber"),
     41  1.1     lukem 	BER_BVC("gidNumber"),
     42  1.1     lukem 	BER_BVC("gecos"),
     43  1.1     lukem 	BER_BVC("cn"),
     44  1.1     lukem 	BER_BVC("homeDirectory"),
     45  1.1     lukem 	BER_BVC("loginShell"),
     46  1.1     lukem 	BER_BVC("objectClass"),
     47  1.1     lukem 	BER_BVNULL
     48  1.1     lukem };
     49  1.1     lukem 
     50  1.1     lukem #define UID_KEY	0
     51  1.1     lukem #define	PWD_KEY	1
     52  1.1     lukem #define UIDN_KEY	2
     53  1.1     lukem #define GIDN_KEY	3
     54  1.1     lukem #define GEC_KEY	4
     55  1.1     lukem #define CN_KEY	5
     56  1.1     lukem #define DIR_KEY	6
     57  1.1     lukem #define SHL_KEY	7
     58  1.1     lukem 
     59  1.1     lukem /* default values for attributes */
     60  1.1     lukem static struct berval default_passwd_userPassword	= BER_BVC("*"); /* unmatchable */
     61  1.1     lukem static struct berval default_passwd_homeDirectory	= BER_BVC("");
     62  1.1     lukem static struct berval default_passwd_loginShell		= BER_BVC("");
     63  1.1     lukem 
     64  1.1     lukem static struct berval shadow_passwd = BER_BVC("x");
     65  1.1     lukem 
     66  1.1     lukem NSSOV_INIT(passwd)
     67  1.1     lukem 
     68  1.1     lukem /*
     69  1.1     lukem 	 Checks to see if the specified name is a valid user name.
     70  1.1     lukem 
     71  1.1     lukem 	 This test is based on the definition from POSIX (IEEE Std 1003.1, 2004, 3.426 User Name
     72  1.1     lukem 	 and 3.276 Portable Filename Character Set):
     73  1.1     lukem 	 http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_426
     74  1.1     lukem 	 http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_276
     75  1.1     lukem 
     76  1.1     lukem 	 The standard defines user names valid if they contain characters from
     77  1.1     lukem 	 the set [A-Za-z0-9._-] where the hyphen should not be used as first
     78  1.1     lukem 	 character. As an extension this test allows the dolar '$' sign as the last
     79  1.1     lukem 	 character to support Samba special accounts.
     80  1.1     lukem */
     81  1.1     lukem int isvalidusername(struct berval *bv)
     82  1.1     lukem {
     83  1.1     lukem 	int i;
     84  1.1     lukem 	char *name = bv->bv_val;
     85  1.1     lukem 	if ((name==NULL)||(name[0]=='\0'))
     86  1.1     lukem 		return 0;
     87  1.1     lukem 	/* check first character */
     88  1.1     lukem 	if ( ! ( (name[0]>='A' && name[0] <= 'Z') ||
     89  1.1     lukem 					 (name[0]>='a' && name[0] <= 'z') ||
     90  1.1     lukem 					 (name[0]>='0' && name[0] <= '9') ||
     91  1.1     lukem 					 name[0]=='.' || name[0]=='_' ) )
     92  1.1     lukem 		return 0;
     93  1.1     lukem 	/* check other characters */
     94  1.1     lukem 	for (i=1;i<bv->bv_len;i++)
     95  1.1     lukem 	{
     96  1.1     lukem 		if ( name[i]=='$' )
     97  1.1     lukem 		{
     98  1.1     lukem 			/* if the char is $ we require it to be the last char */
     99  1.1     lukem 			if (name[i+1]!='\0')
    100  1.1     lukem 				return 0;
    101  1.1     lukem 		}
    102  1.1     lukem 		else if ( ! ( (name[i]>='A' && name[i] <= 'Z') ||
    103  1.1     lukem 									(name[i]>='a' && name[i] <= 'z') ||
    104  1.1     lukem 									(name[i]>='0' && name[i] <= '9') ||
    105  1.1     lukem 									name[i]=='.' || name[i]=='_'	|| name[i]=='-') )
    106  1.1     lukem 			return 0;
    107  1.1     lukem 	}
    108  1.1     lukem 	/* no test failed so it must be good */
    109  1.1     lukem 	return -1;
    110  1.1     lukem }
    111  1.1     lukem 
    112  1.1     lukem /* return 1 on success */
    113  1.1     lukem int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *uid)
    114  1.1     lukem {
    115  1.1     lukem 	nssov_mapinfo *mi = &ni->ni_maps[NM_passwd];
    116  1.1     lukem 	AttributeDescription *ad = mi->mi_attrs[UID_KEY].an_desc;
    117  1.1     lukem 	Entry *e;
    118  1.1     lukem 
    119  1.1     lukem 	/* check for empty string */
    120  1.1     lukem 	if (!dn->bv_len)
    121  1.1     lukem 		return 0;
    122  1.1     lukem 	/* try to look up uid within DN string */
    123  1.1     lukem 	if (!strncmp(dn->bv_val,ad->ad_cname.bv_val,ad->ad_cname.bv_len) &&
    124  1.1     lukem 		dn->bv_val[ad->ad_cname.bv_len] == '=')
    125  1.1     lukem 	{
    126  1.1     lukem 		struct berval bv, rdn;
    127  1.1     lukem 		dnRdn(dn, &rdn);
    128  1.1     lukem 		/* check if it is valid */
    129  1.1     lukem 		bv.bv_val = dn->bv_val + ad->ad_cname.bv_len + 1;
    130  1.1     lukem 		bv.bv_len = rdn.bv_len - ad->ad_cname.bv_len - 1;
    131  1.1     lukem 		if (!isvalidusername(&bv))
    132  1.1     lukem 			return 0;
    133  1.1     lukem 		ber_dupbv_x( uid, &bv, op->o_tmpmemctx );
    134  1.1     lukem 		return 1;
    135  1.1     lukem 	}
    136  1.1     lukem 	/* look up the uid from the entry itself */
    137  1.1     lukem 	if (be_entry_get_rw( op, dn, NULL, ad, 0, &e) == LDAP_SUCCESS)
    138  1.1     lukem 	{
    139  1.1     lukem 		Attribute *a = attr_find(e->e_attrs, ad);
    140  1.1     lukem 		if (a) {
    141  1.1     lukem 			ber_dupbv_x(uid, &a->a_vals[0], op->o_tmpmemctx);
    142  1.1     lukem 		}
    143  1.1     lukem 		be_entry_release_r(op, e);
    144  1.1     lukem 		if (a)
    145  1.1     lukem 			return 1;
    146  1.1     lukem 	}
    147  1.1     lukem 	return 0;
    148  1.1     lukem }
    149  1.1     lukem 
    150  1.2  christos int nssov_name2dn_cb(Operation *op,SlapReply *rs)
    151  1.1     lukem {
    152  1.1     lukem 	if ( rs->sr_type == REP_SEARCH )
    153  1.1     lukem 	{
    154  1.1     lukem 		struct berval *bv = op->o_callback->sc_private;
    155  1.1     lukem 		if ( !BER_BVISNULL(bv)) {
    156  1.1     lukem 			op->o_tmpfree( bv->bv_val, op->o_tmpmemctx );
    157  1.1     lukem 			BER_BVZERO(bv);
    158  1.1     lukem 			return LDAP_ALREADY_EXISTS;
    159  1.1     lukem 		}
    160  1.1     lukem 		ber_dupbv_x(bv, &rs->sr_entry->e_name, op->o_tmpmemctx);
    161  1.1     lukem 	}
    162  1.1     lukem 	return LDAP_SUCCESS;
    163  1.1     lukem }
    164  1.1     lukem 
    165  1.1     lukem int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn)
    166  1.1     lukem {
    167  1.1     lukem 	nssov_mapinfo *mi = &ni->ni_maps[NM_passwd];
    168  1.1     lukem 	char fbuf[1024];
    169  1.1     lukem 	struct berval filter = {sizeof(fbuf),fbuf};
    170  1.1     lukem 	slap_callback cb = {0};
    171  1.1     lukem 	SlapReply rs = {REP_RESULT};
    172  1.1     lukem 	Operation op2;
    173  1.1     lukem 	int rc;
    174  1.1     lukem 
    175  1.1     lukem 	/* if it isn't a valid username, just bail out now */
    176  1.1     lukem 	if (!isvalidusername(uid))
    177  1.1     lukem 		return 0;
    178  1.1     lukem 	/* we have to look up the entry */
    179  1.2  christos 	nssov_filter_byid(mi,UID_KEY,uid,&filter);
    180  1.1     lukem 	BER_BVZERO(dn);
    181  1.1     lukem 	cb.sc_private = dn;
    182  1.2  christos 	cb.sc_response = nssov_name2dn_cb;
    183  1.1     lukem 	op2 = *op;
    184  1.1     lukem 	op2.o_callback = &cb;
    185  1.1     lukem 	op2.o_req_dn = mi->mi_base;
    186  1.1     lukem 	op2.o_req_ndn = mi->mi_base;
    187  1.1     lukem 	op2.ors_scope = mi->mi_scope;
    188  1.1     lukem 	op2.ors_filterstr = filter;
    189  1.1     lukem 	op2.ors_filter = str2filter_x( op, filter.bv_val );
    190  1.1     lukem 	op2.ors_attrs = slap_anlist_no_attrs;
    191  1.2  christos 	op2.ors_tlimit = SLAP_NO_LIMIT;
    192  1.2  christos 	op2.ors_slimit = SLAP_NO_LIMIT;
    193  1.1     lukem 	rc = op2.o_bd->be_search( &op2, &rs );
    194  1.2  christos 	filter_free_x( op, op2.ors_filter, 1 );
    195  1.2  christos 	return rc == LDAP_SUCCESS && !BER_BVISNULL(dn);
    196  1.1     lukem }
    197  1.1     lukem 
    198  1.1     lukem /* the maximum number of uidNumber attributes per entry */
    199  1.1     lukem #define MAXUIDS_PER_ENTRY 5
    200  1.1     lukem 
    201  1.1     lukem NSSOV_CBPRIV(passwd,
    202  1.1     lukem 	char buf[256];
    203  1.1     lukem 	struct berval name;
    204  1.1     lukem 	struct berval id;);
    205  1.1     lukem 
    206  1.1     lukem static struct berval shadowclass = BER_BVC("shadowAccount");
    207  1.1     lukem 
    208  1.1     lukem static int write_passwd(nssov_passwd_cbp *cbp,Entry *entry)
    209  1.1     lukem {
    210  1.1     lukem 	int32_t tmpint32;
    211  1.1     lukem 	struct berval tmparr[2], tmpuid[2];
    212  1.1     lukem 	char *tmp;
    213  1.1     lukem 	struct berval *names;
    214  1.1     lukem 	struct berval *uids;
    215  1.1     lukem 	struct berval passwd = {0};
    216  1.1     lukem 	gid_t gid;
    217  1.1     lukem 	struct berval gecos;
    218  1.1     lukem 	struct berval homedir;
    219  1.1     lukem 	struct berval shell;
    220  1.1     lukem 	Attribute *a;
    221  1.1     lukem 	int i,j;
    222  1.1     lukem 	int use_shadow = 0;
    223  1.1     lukem 	/* get the usernames for this entry */
    224  1.1     lukem 	if (BER_BVISNULL(&cbp->name))
    225  1.1     lukem 	{
    226  1.1     lukem 		a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[UID_KEY].an_desc);
    227  1.1     lukem 		if (!a)
    228  1.1     lukem 		{
    229  1.2  christos 			Debug(LDAP_DEBUG_ANY,"passwd entry %s does not contain %s value\n",
    230  1.3  christos 				entry->e_name.bv_val, cbp->mi->mi_attrs[UID_KEY].an_desc->ad_cname.bv_val );
    231  1.1     lukem 			return 0;
    232  1.1     lukem 		}
    233  1.1     lukem 		names = a->a_vals;
    234  1.1     lukem 	}
    235  1.1     lukem 	else
    236  1.1     lukem 	{
    237  1.1     lukem 		names=tmparr;
    238  1.1     lukem 		names[0]=cbp->name;
    239  1.1     lukem 		BER_BVZERO(&names[1]);
    240  1.1     lukem 	}
    241  1.1     lukem 	/* get the password for this entry */
    242  1.1     lukem 	a = attr_find(entry->e_attrs, slap_schema.si_ad_objectClass);
    243  1.1     lukem 	if ( a ) {
    244  1.1     lukem 		for ( i=0; i<a->a_numvals; i++) {
    245  1.1     lukem 			if ( bvmatch( &shadowclass, &a->a_nvals[i] )) {
    246  1.1     lukem 				use_shadow = 1;
    247  1.1     lukem 				break;
    248  1.1     lukem 			}
    249  1.1     lukem 		}
    250  1.1     lukem 	}
    251  1.1     lukem 	if ( use_shadow )
    252  1.1     lukem 	{
    253  1.1     lukem 		/* if the entry has a shadowAccount entry, point to that instead */
    254  1.1     lukem 		passwd = shadow_passwd;
    255  1.1     lukem 	}
    256  1.1     lukem 	else
    257  1.1     lukem 	{
    258  1.1     lukem 		a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[PWD_KEY].an_desc);
    259  1.1     lukem 		if (a)
    260  1.1     lukem 			get_userpassword(&a->a_vals[0], &passwd);
    261  1.1     lukem 		if (BER_BVISNULL(&passwd))
    262  1.1     lukem 			passwd=default_passwd_userPassword;
    263  1.1     lukem 	}
    264  1.1     lukem 	/* get the uids for this entry */
    265  1.1     lukem 	if (BER_BVISNULL(&cbp->id))
    266  1.1     lukem 	{
    267  1.1     lukem 		a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[UIDN_KEY].an_desc);
    268  1.1     lukem         if ( !a )
    269  1.1     lukem 		{
    270  1.2  christos 			Debug(LDAP_DEBUG_ANY,"passwd entry %s does not contain %s value\n",
    271  1.3  christos 				entry->e_name.bv_val, cbp->mi->mi_attrs[UIDN_KEY].an_desc->ad_cname.bv_val );
    272  1.1     lukem 			return 0;
    273  1.1     lukem 		}
    274  1.1     lukem 		uids = a->a_vals;
    275  1.1     lukem 	}
    276  1.1     lukem 	else
    277  1.1     lukem 	{
    278  1.1     lukem 		uids = tmpuid;
    279  1.1     lukem 		uids[0] = cbp->id;
    280  1.1     lukem 		BER_BVZERO(&uids[1]);
    281  1.1     lukem 	}
    282  1.1     lukem 	/* get the gid for this entry */
    283  1.1     lukem 	a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[GIDN_KEY].an_desc);
    284  1.1     lukem 	if (!a)
    285  1.1     lukem 	{
    286  1.2  christos 		Debug(LDAP_DEBUG_ANY,"passwd entry %s does not contain %s value\n",
    287  1.3  christos 			entry->e_name.bv_val, cbp->mi->mi_attrs[GIDN_KEY].an_desc->ad_cname.bv_val );
    288  1.1     lukem 		return 0;
    289  1.1     lukem 	}
    290  1.1     lukem 	else if (a->a_numvals != 1)
    291  1.1     lukem 	{
    292  1.2  christos 		Debug(LDAP_DEBUG_ANY,"passwd entry %s contains multiple %s values\n",
    293  1.3  christos 			entry->e_name.bv_val, cbp->mi->mi_attrs[GIDN_KEY].an_desc->ad_cname.bv_val );
    294  1.1     lukem 	}
    295  1.1     lukem 	gid=(gid_t)strtol(a->a_vals[0].bv_val,&tmp,0);
    296  1.1     lukem 	if ((a->a_vals[0].bv_val[0]=='\0')||(*tmp!='\0'))
    297  1.1     lukem 	{
    298  1.2  christos 		Debug(LDAP_DEBUG_ANY,"passwd entry %s contains non-numeric %s value\n",
    299  1.3  christos 			entry->e_name.bv_val, cbp->mi->mi_attrs[GIDN_KEY].an_desc->ad_cname.bv_val );
    300  1.1     lukem 		return 0;
    301  1.1     lukem 	}
    302  1.1     lukem 	/* get the gecos for this entry (fall back to cn) */
    303  1.1     lukem 	a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[GEC_KEY].an_desc);
    304  1.1     lukem 	if (!a)
    305  1.1     lukem 		a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[CN_KEY].an_desc);
    306  1.1     lukem 	if (!a || !a->a_numvals)
    307  1.1     lukem 	{
    308  1.2  christos 		Debug(LDAP_DEBUG_ANY,"passwd entry %s does not contain %s or %s value\n",
    309  1.1     lukem 			entry->e_name.bv_val,
    310  1.1     lukem 			cbp->mi->mi_attrs[GEC_KEY].an_desc->ad_cname.bv_val,
    311  1.1     lukem 			cbp->mi->mi_attrs[CN_KEY].an_desc->ad_cname.bv_val);
    312  1.1     lukem 		return 0;
    313  1.1     lukem 	}
    314  1.1     lukem 	else if (a->a_numvals > 1)
    315  1.1     lukem 	{
    316  1.2  christos 		Debug(LDAP_DEBUG_ANY,"passwd entry %s contains multiple %s or %s values\n",
    317  1.1     lukem 			entry->e_name.bv_val,
    318  1.1     lukem 			cbp->mi->mi_attrs[GEC_KEY].an_desc->ad_cname.bv_val,
    319  1.1     lukem 			cbp->mi->mi_attrs[CN_KEY].an_desc->ad_cname.bv_val);
    320  1.1     lukem 	}
    321  1.1     lukem 	gecos=a->a_vals[0];
    322  1.1     lukem 	/* get the home directory for this entry */
    323  1.1     lukem 	a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[DIR_KEY].an_desc);
    324  1.1     lukem 	if (!a)
    325  1.1     lukem 	{
    326  1.2  christos 		Debug(LDAP_DEBUG_ANY,"passwd entry %s does not contain %s value\n",
    327  1.3  christos 			entry->e_name.bv_val, cbp->mi->mi_attrs[DIR_KEY].an_desc->ad_cname.bv_val );
    328  1.1     lukem 		homedir=default_passwd_homeDirectory;
    329  1.1     lukem 	}
    330  1.1     lukem 	else
    331  1.1     lukem 	{
    332  1.1     lukem 		if (a->a_numvals > 1)
    333  1.1     lukem 		{
    334  1.2  christos 			Debug(LDAP_DEBUG_ANY,"passwd entry %s contains multiple %s values\n",
    335  1.3  christos 				entry->e_name.bv_val, cbp->mi->mi_attrs[DIR_KEY].an_desc->ad_cname.bv_val );
    336  1.1     lukem 		}
    337  1.1     lukem 		homedir=a->a_vals[0];
    338  1.1     lukem 		if (homedir.bv_val[0]=='\0')
    339  1.1     lukem 			homedir=default_passwd_homeDirectory;
    340  1.1     lukem 	}
    341  1.1     lukem 	/* get the shell for this entry */
    342  1.1     lukem 	a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[SHL_KEY].an_desc);
    343  1.1     lukem 	if (!a)
    344  1.1     lukem 	{
    345  1.1     lukem 		shell=default_passwd_loginShell;
    346  1.1     lukem 	}
    347  1.1     lukem 	else
    348  1.1     lukem 	{
    349  1.1     lukem 		if (a->a_numvals > 1)
    350  1.1     lukem 		{
    351  1.2  christos 			Debug(LDAP_DEBUG_ANY,"passwd entry %s contains multiple %s values\n",
    352  1.3  christos 				entry->e_name.bv_val, cbp->mi->mi_attrs[SHL_KEY].an_desc->ad_cname.bv_val );
    353  1.1     lukem 		}
    354  1.1     lukem 		shell=a->a_vals[0];
    355  1.1     lukem 		if (shell.bv_val[0]=='\0')
    356  1.1     lukem 			shell=default_passwd_loginShell;
    357  1.1     lukem 	}
    358  1.1     lukem 	/* write the entries */
    359  1.1     lukem 	for (i=0;!BER_BVISNULL(&names[i]);i++)
    360  1.1     lukem 	{
    361  1.1     lukem 		if (!isvalidusername(&names[i]))
    362  1.1     lukem 		{
    363  1.2  christos 			Debug(LDAP_DEBUG_ANY,"nssov: passwd entry %s contains invalid user name: \"%s\"\n",
    364  1.3  christos 				entry->e_name.bv_val,names[i].bv_val );
    365  1.1     lukem 		}
    366  1.1     lukem 		else
    367  1.1     lukem 		{
    368  1.1     lukem 			for (j=0;!BER_BVISNULL(&uids[j]);j++)
    369  1.1     lukem 			{
    370  1.1     lukem 				char *tmp;
    371  1.1     lukem 				uid_t uid;
    372  1.1     lukem 				uid = strtol(uids[j].bv_val, &tmp, 0);
    373  1.1     lukem 				if ( *tmp ) {
    374  1.2  christos 					Debug(LDAP_DEBUG_ANY,"nssov: passwd entry %s contains non-numeric %s value: \"%s\"\n",
    375  1.1     lukem 						entry->e_name.bv_val, cbp->mi->mi_attrs[UIDN_KEY].an_desc->ad_cname.bv_val,
    376  1.1     lukem 						names[i].bv_val);
    377  1.1     lukem 					continue;
    378  1.1     lukem 				}
    379  1.2  christos 				WRITE_INT32(cbp->fp,NSLCD_RESULT_BEGIN);
    380  1.1     lukem 				WRITE_BERVAL(cbp->fp,&names[i]);
    381  1.1     lukem 				WRITE_BERVAL(cbp->fp,&passwd);
    382  1.2  christos 				WRITE_INT32(cbp->fp,uid);
    383  1.2  christos 				WRITE_INT32(cbp->fp,gid);
    384  1.1     lukem 				WRITE_BERVAL(cbp->fp,&gecos);
    385  1.1     lukem 				WRITE_BERVAL(cbp->fp,&homedir);
    386  1.1     lukem 				WRITE_BERVAL(cbp->fp,&shell);
    387  1.1     lukem 			}
    388  1.1     lukem 		}
    389  1.1     lukem 	}
    390  1.1     lukem 	return 0;
    391  1.1     lukem }
    392  1.1     lukem 
    393  1.1     lukem NSSOV_CB(passwd)
    394  1.1     lukem 
    395  1.1     lukem NSSOV_HANDLE(
    396  1.1     lukem 	passwd,byname,
    397  1.1     lukem 	char fbuf[1024];
    398  1.1     lukem 	struct berval filter = {sizeof(fbuf)};
    399  1.1     lukem 	filter.bv_val = fbuf;
    400  1.2  christos 	READ_STRING(fp,cbp.buf);
    401  1.1     lukem 	cbp.name.bv_len = tmpint32;
    402  1.1     lukem 	cbp.name.bv_val = cbp.buf;
    403  1.1     lukem 	if (!isvalidusername(&cbp.name)) {
    404  1.3  christos 		Debug(LDAP_DEBUG_ANY,"nssov_passwd_byname(%s): invalid user name\n",cbp.name.bv_val);
    405  1.1     lukem 		return -1;
    406  1.1     lukem 	}
    407  1.1     lukem 	BER_BVZERO(&cbp.id); ,
    408  1.3  christos 	Debug(LDAP_DEBUG_TRACE,"nssov_passwd_byname(%s)\n",cbp.name.bv_val);,
    409  1.1     lukem 	NSLCD_ACTION_PASSWD_BYNAME,
    410  1.1     lukem 	nssov_filter_byname(cbp.mi,UID_KEY,&cbp.name,&filter)
    411  1.1     lukem )
    412  1.1     lukem 
    413  1.1     lukem NSSOV_HANDLE(
    414  1.1     lukem 	passwd,byuid,
    415  1.1     lukem 	uid_t uid;
    416  1.1     lukem 	char fbuf[1024];
    417  1.1     lukem 	struct berval filter = {sizeof(fbuf)};
    418  1.1     lukem 	filter.bv_val = fbuf;
    419  1.2  christos 	READ_INT32(fp,uid);
    420  1.1     lukem 	cbp.id.bv_val = cbp.buf;
    421  1.1     lukem 	cbp.id.bv_len = snprintf(cbp.buf,sizeof(cbp.buf),"%d",uid);
    422  1.1     lukem 	BER_BVZERO(&cbp.name);,
    423  1.3  christos 	Debug(LDAP_DEBUG_TRACE,"nssov_passwd_byuid(%s)\n",cbp.id.bv_val);,
    424  1.1     lukem 	NSLCD_ACTION_PASSWD_BYUID,
    425  1.1     lukem 	nssov_filter_byid(cbp.mi,UIDN_KEY,&cbp.id,&filter)
    426  1.1     lukem )
    427  1.1     lukem 
    428  1.1     lukem NSSOV_HANDLE(
    429  1.1     lukem 	passwd,all,
    430  1.1     lukem 	struct berval filter;
    431  1.1     lukem 	/* no parameters to read */
    432  1.1     lukem 	BER_BVZERO(&cbp.name);
    433  1.1     lukem 	BER_BVZERO(&cbp.id);,
    434  1.3  christos 	Debug(LDAP_DEBUG_TRACE,"nssov_passwd_all()\n");,
    435  1.1     lukem 	NSLCD_ACTION_PASSWD_ALL,
    436  1.1     lukem 	(filter=cbp.mi->mi_filter,0)
    437  1.1     lukem )
    438