static struct mypasswd *mypwenter(const struct passwd * pwd) { struct mypasswd *mypwd; /* * Initialize on the fly. */ if (mypwcache_name == 0) { mypwcache_name = htable_create(0); mypwcache_uid = binhash_create(0); } mypwd = (struct mypasswd *) mymalloc(sizeof(*mypwd)); mypwd->refcount = 0; mypwd->pw_name = mystrdup(pwd->pw_name); mypwd->pw_passwd = mystrdup(pwd->pw_passwd); mypwd->pw_uid = pwd->pw_uid; mypwd->pw_gid = pwd->pw_gid; mypwd->pw_gecos = mystrdup(pwd->pw_gecos); mypwd->pw_dir = mystrdup(pwd->pw_dir); mypwd->pw_shell = mystrdup(*pwd->pw_shell ? pwd->pw_shell : _PATH_BSHELL); /* * Avoid mypwcache_uid memory leak when multiple names have the same UID. * This makes the lookup result dependent on program history. But, it was * already history-dependent before we added this extra check. */ htable_enter(mypwcache_name, mypwd->pw_name, (char *) mypwd); if (binhash_locate(mypwcache_uid, (char *) &mypwd->pw_uid, sizeof(mypwd->pw_uid)) == 0) binhash_enter(mypwcache_uid, (char *) &mypwd->pw_uid, sizeof(mypwd->pw_uid), (char *) mypwd); return (mypwd); }
/* * Locate or allocate connection cache entry. */ static void dict_ldap_conn_find(DICT_LDAP *dict_ldap) { VSTRING *keybuf = vstring_alloc(10); char *key; int len; #ifdef LDAP_API_FEATURE_X_OPENLDAP int sslon = dict_ldap->start_tls || dict_ldap->ldap_ssl; #endif LDAP_CONN *conn; #define ADDSTR(vp, s) vstring_memcat((vp), (s), strlen((s))+1) #define ADDINT(vp, i) vstring_sprintf_append((vp), "%lu", (unsigned long)(i)) ADDSTR(keybuf, dict_ldap->server_host); ADDINT(keybuf, dict_ldap->server_port); ADDINT(keybuf, dict_ldap->bind); ADDSTR(keybuf, dict_ldap->bind ? dict_ldap->bind_dn : ""); ADDSTR(keybuf, dict_ldap->bind ? dict_ldap->bind_pw : ""); ADDINT(keybuf, dict_ldap->dereference); ADDINT(keybuf, dict_ldap->chase_referrals); ADDINT(keybuf, dict_ldap->debuglevel); ADDINT(keybuf, dict_ldap->version); #ifdef LDAP_API_FEATURE_X_OPENLDAP ADDINT(keybuf, dict_ldap->ldap_ssl); ADDINT(keybuf, dict_ldap->start_tls); ADDINT(keybuf, sslon ? dict_ldap->tls_require_cert : 0); ADDSTR(keybuf, sslon ? dict_ldap->tls_ca_cert_file : ""); ADDSTR(keybuf, sslon ? dict_ldap->tls_ca_cert_dir : ""); ADDSTR(keybuf, sslon ? dict_ldap->tls_cert : ""); ADDSTR(keybuf, sslon ? dict_ldap->tls_key : ""); ADDSTR(keybuf, sslon ? dict_ldap->tls_random_file : ""); ADDSTR(keybuf, sslon ? dict_ldap->tls_cipher_suite : ""); #endif key = vstring_str(keybuf); len = VSTRING_LEN(keybuf); if (conn_hash == 0) conn_hash = binhash_create(0); if ((dict_ldap->ht = binhash_locate(conn_hash, key, len)) == 0) { conn = (LDAP_CONN *) mymalloc(sizeof(LDAP_CONN)); conn->conn_ld = 0; conn->conn_refcount = 0; dict_ldap->ht = binhash_enter(conn_hash, key, len, (char *) conn); } ++DICT_LDAP_CONN(dict_ldap)->conn_refcount; vstring_free(keybuf); }
void mypwfree(struct mypasswd * mypwd) { if (mypwd->refcount < 1) msg_panic("mypwfree: refcount %d", mypwd->refcount); /* * See mypwenter() for the reason behind the binhash_locate() test. */ if (--mypwd->refcount == 0) { htable_delete(mypwcache_name, mypwd->pw_name, (void (*) (char *)) 0); if (binhash_locate(mypwcache_uid, (char *) &mypwd->pw_uid, sizeof(mypwd->pw_uid))) binhash_delete(mypwcache_uid, (char *) &mypwd->pw_uid, sizeof(mypwd->pw_uid), (void (*) (char *)) 0); myfree(mypwd->pw_name); myfree(mypwd->pw_passwd); myfree(mypwd->pw_gecos); myfree(mypwd->pw_dir); myfree(mypwd->pw_shell); myfree((char *) mypwd); } }