xref: /freebsd/contrib/sendmail/libsm/mbdb.c (revision 4026605903c0ab8df33c4ae8c419acdb2b652af8)
140266059SGregory Neil Shapiro /*
240266059SGregory Neil Shapiro  * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers.
340266059SGregory Neil Shapiro  *      All rights reserved.
440266059SGregory Neil Shapiro  *
540266059SGregory Neil Shapiro  * By using this file, you agree to the terms and conditions set
640266059SGregory Neil Shapiro  * forth in the LICENSE file which can be found at the top level of
740266059SGregory Neil Shapiro  * the sendmail distribution.
840266059SGregory Neil Shapiro  */
940266059SGregory Neil Shapiro 
1040266059SGregory Neil Shapiro #include <sm/gen.h>
1140266059SGregory Neil Shapiro SM_RCSID("@(#)$Id: mbdb.c,v 1.28 2002/01/07 23:29:43 gshapiro Exp $")
1240266059SGregory Neil Shapiro 
1340266059SGregory Neil Shapiro #include <sys/param.h>
1440266059SGregory Neil Shapiro 
1540266059SGregory Neil Shapiro #include <ctype.h>
1640266059SGregory Neil Shapiro #include <errno.h>
1740266059SGregory Neil Shapiro #include <pwd.h>
1840266059SGregory Neil Shapiro #include <stdlib.h>
1940266059SGregory Neil Shapiro #include <setjmp.h>
2040266059SGregory Neil Shapiro 
2140266059SGregory Neil Shapiro #include <sm/limits.h>
2240266059SGregory Neil Shapiro #include <sm/conf.h>
2340266059SGregory Neil Shapiro #include <sm/assert.h>
2440266059SGregory Neil Shapiro #include <sm/bitops.h>
2540266059SGregory Neil Shapiro #include <sm/errstring.h>
2640266059SGregory Neil Shapiro #include <sm/heap.h>
2740266059SGregory Neil Shapiro #include <sm/mbdb.h>
2840266059SGregory Neil Shapiro #include <sm/string.h>
2940266059SGregory Neil Shapiro #include <sm/sysexits.h>
3040266059SGregory Neil Shapiro 
3140266059SGregory Neil Shapiro #if LDAPMAP
3240266059SGregory Neil Shapiro # if _LDAP_EXAMPLE_
3340266059SGregory Neil Shapiro #  include <sm/ldap.h>
3440266059SGregory Neil Shapiro # endif /* _LDAP_EXAMPLE_ */
3540266059SGregory Neil Shapiro #endif /* LDAPMAP */
3640266059SGregory Neil Shapiro 
3740266059SGregory Neil Shapiro typedef struct
3840266059SGregory Neil Shapiro {
3940266059SGregory Neil Shapiro 	char	*mbdb_typename;
4040266059SGregory Neil Shapiro 	int	(*mbdb_initialize) __P((char *));
4140266059SGregory Neil Shapiro 	int	(*mbdb_lookup) __P((char *name, SM_MBDB_T *user));
4240266059SGregory Neil Shapiro 	void	(*mbdb_terminate) __P((void));
4340266059SGregory Neil Shapiro } SM_MBDB_TYPE_T;
4440266059SGregory Neil Shapiro 
4540266059SGregory Neil Shapiro static int	mbdb_pw_initialize __P((char *));
4640266059SGregory Neil Shapiro static int	mbdb_pw_lookup __P((char *name, SM_MBDB_T *user));
4740266059SGregory Neil Shapiro static void	mbdb_pw_terminate __P((void));
4840266059SGregory Neil Shapiro 
4940266059SGregory Neil Shapiro #if LDAPMAP
5040266059SGregory Neil Shapiro # if _LDAP_EXAMPLE_
5140266059SGregory Neil Shapiro static struct sm_ldap_struct LDAPLMAP;
5240266059SGregory Neil Shapiro static int	mbdb_ldap_initialize __P((char *));
5340266059SGregory Neil Shapiro static int	mbdb_ldap_lookup __P((char *name, SM_MBDB_T *user));
5440266059SGregory Neil Shapiro static void	mbdb_ldap_terminate __P((void));
5540266059SGregory Neil Shapiro # endif /* _LDAP_EXAMPLE_ */
5640266059SGregory Neil Shapiro #endif /* LDAPMAP */
5740266059SGregory Neil Shapiro 
5840266059SGregory Neil Shapiro static SM_MBDB_TYPE_T SmMbdbTypes[] =
5940266059SGregory Neil Shapiro {
6040266059SGregory Neil Shapiro 	{ "pw", mbdb_pw_initialize, mbdb_pw_lookup, mbdb_pw_terminate },
6140266059SGregory Neil Shapiro #if LDAPMAP
6240266059SGregory Neil Shapiro # if _LDAP_EXAMPLE_
6340266059SGregory Neil Shapiro 	{ "ldap", mbdb_ldap_initialize, mbdb_ldap_lookup, mbdb_ldap_terminate },
6440266059SGregory Neil Shapiro # endif /* _LDAP_EXAMPLE_ */
6540266059SGregory Neil Shapiro #endif /* LDAPMAP */
6640266059SGregory Neil Shapiro 	{ NULL, NULL, NULL, NULL }
6740266059SGregory Neil Shapiro };
6840266059SGregory Neil Shapiro 
6940266059SGregory Neil Shapiro static SM_MBDB_TYPE_T *SmMbdbType = &SmMbdbTypes[0];
7040266059SGregory Neil Shapiro 
7140266059SGregory Neil Shapiro /*
7240266059SGregory Neil Shapiro **  SM_MBDB_INITIALIZE -- specify which mailbox database to use
7340266059SGregory Neil Shapiro **
7440266059SGregory Neil Shapiro **	If this function is not called, then the "pw" implementation
7540266059SGregory Neil Shapiro **	is used by default; this implementation uses getpwnam().
7640266059SGregory Neil Shapiro **
7740266059SGregory Neil Shapiro **	Parameters:
7840266059SGregory Neil Shapiro **		mbdb -- Which mailbox database to use.
7940266059SGregory Neil Shapiro **			The argument has the form "name" or "name.arg".
8040266059SGregory Neil Shapiro **			"pw" means use getpwnam().
8140266059SGregory Neil Shapiro **
8240266059SGregory Neil Shapiro **	Results:
8340266059SGregory Neil Shapiro **		EX_OK on success, or an EX_* code on failure.
8440266059SGregory Neil Shapiro */
8540266059SGregory Neil Shapiro 
8640266059SGregory Neil Shapiro int
8740266059SGregory Neil Shapiro sm_mbdb_initialize(mbdb)
8840266059SGregory Neil Shapiro 	char *mbdb;
8940266059SGregory Neil Shapiro {
9040266059SGregory Neil Shapiro 	size_t namelen;
9140266059SGregory Neil Shapiro 	int err;
9240266059SGregory Neil Shapiro 	char *name;
9340266059SGregory Neil Shapiro 	char *arg;
9440266059SGregory Neil Shapiro 	SM_MBDB_TYPE_T *t;
9540266059SGregory Neil Shapiro 
9640266059SGregory Neil Shapiro 	SM_REQUIRE(mbdb != NULL);
9740266059SGregory Neil Shapiro 
9840266059SGregory Neil Shapiro 	name = mbdb;
9940266059SGregory Neil Shapiro 	arg = strchr(mbdb, '.');
10040266059SGregory Neil Shapiro 	if (arg == NULL)
10140266059SGregory Neil Shapiro 		namelen = strlen(name);
10240266059SGregory Neil Shapiro 	else
10340266059SGregory Neil Shapiro 	{
10440266059SGregory Neil Shapiro 		namelen = arg - name;
10540266059SGregory Neil Shapiro 		++arg;
10640266059SGregory Neil Shapiro 	}
10740266059SGregory Neil Shapiro 
10840266059SGregory Neil Shapiro 	for (t = SmMbdbTypes; t->mbdb_typename != NULL; ++t)
10940266059SGregory Neil Shapiro 	{
11040266059SGregory Neil Shapiro 		if (strlen(t->mbdb_typename) == namelen &&
11140266059SGregory Neil Shapiro 		    strncmp(name, t->mbdb_typename, namelen) == 0)
11240266059SGregory Neil Shapiro 		{
11340266059SGregory Neil Shapiro 			err = t->mbdb_initialize(arg);
11440266059SGregory Neil Shapiro 			if (err == EX_OK)
11540266059SGregory Neil Shapiro 				SmMbdbType = t;
11640266059SGregory Neil Shapiro 			return err;
11740266059SGregory Neil Shapiro 		}
11840266059SGregory Neil Shapiro 	}
11940266059SGregory Neil Shapiro 	return EX_UNAVAILABLE;
12040266059SGregory Neil Shapiro }
12140266059SGregory Neil Shapiro 
12240266059SGregory Neil Shapiro /*
12340266059SGregory Neil Shapiro **  SM_MBDB_TERMINATE -- terminate connection to the mailbox database
12440266059SGregory Neil Shapiro **
12540266059SGregory Neil Shapiro **	Because this function closes any cached file descriptors that
12640266059SGregory Neil Shapiro **	are being held open for the connection to the mailbox database,
12740266059SGregory Neil Shapiro **	it should be called for security reasons prior to dropping privileges
12840266059SGregory Neil Shapiro **	and execing another process.
12940266059SGregory Neil Shapiro **
13040266059SGregory Neil Shapiro **	Parameters:
13140266059SGregory Neil Shapiro **		none.
13240266059SGregory Neil Shapiro **
13340266059SGregory Neil Shapiro **	Results:
13440266059SGregory Neil Shapiro **		none.
13540266059SGregory Neil Shapiro */
13640266059SGregory Neil Shapiro 
13740266059SGregory Neil Shapiro void
13840266059SGregory Neil Shapiro sm_mbdb_terminate()
13940266059SGregory Neil Shapiro {
14040266059SGregory Neil Shapiro 	SmMbdbType->mbdb_terminate();
14140266059SGregory Neil Shapiro }
14240266059SGregory Neil Shapiro 
14340266059SGregory Neil Shapiro /*
14440266059SGregory Neil Shapiro **  SM_MBDB_LOOKUP -- look up a local mail recipient, given name
14540266059SGregory Neil Shapiro **
14640266059SGregory Neil Shapiro **	Parameters:
14740266059SGregory Neil Shapiro **		name -- name of local mail recipient
14840266059SGregory Neil Shapiro **		user -- pointer to structure to fill in on success
14940266059SGregory Neil Shapiro **
15040266059SGregory Neil Shapiro **	Results:
15140266059SGregory Neil Shapiro **		On success, fill in *user and return EX_OK.
15240266059SGregory Neil Shapiro **		If the user does not exist, return EX_NOUSER.
15340266059SGregory Neil Shapiro **		If a temporary failure (eg, a network failure) occurred,
15440266059SGregory Neil Shapiro **		return EX_TEMPFAIL.  Otherwise return EX_OSERR.
15540266059SGregory Neil Shapiro */
15640266059SGregory Neil Shapiro 
15740266059SGregory Neil Shapiro int
15840266059SGregory Neil Shapiro sm_mbdb_lookup(name, user)
15940266059SGregory Neil Shapiro 	char *name;
16040266059SGregory Neil Shapiro 	SM_MBDB_T *user;
16140266059SGregory Neil Shapiro {
16240266059SGregory Neil Shapiro 	return SmMbdbType->mbdb_lookup(name, user);
16340266059SGregory Neil Shapiro }
16440266059SGregory Neil Shapiro 
16540266059SGregory Neil Shapiro /*
16640266059SGregory Neil Shapiro **  SM_MBDB_FROMPW -- copy from struct pw to SM_MBDB_T
16740266059SGregory Neil Shapiro **
16840266059SGregory Neil Shapiro **	Parameters:
16940266059SGregory Neil Shapiro **		user -- destination user information structure
17040266059SGregory Neil Shapiro **		pw -- source passwd structure
17140266059SGregory Neil Shapiro **
17240266059SGregory Neil Shapiro **	Results:
17340266059SGregory Neil Shapiro **		none.
17440266059SGregory Neil Shapiro */
17540266059SGregory Neil Shapiro 
17640266059SGregory Neil Shapiro void
17740266059SGregory Neil Shapiro sm_mbdb_frompw(user, pw)
17840266059SGregory Neil Shapiro 	SM_MBDB_T *user;
17940266059SGregory Neil Shapiro 	struct passwd *pw;
18040266059SGregory Neil Shapiro {
18140266059SGregory Neil Shapiro 	SM_REQUIRE(user != NULL);
18240266059SGregory Neil Shapiro 	(void) sm_strlcpy(user->mbdb_name, pw->pw_name,
18340266059SGregory Neil Shapiro 			  sizeof(user->mbdb_name));
18440266059SGregory Neil Shapiro 	user->mbdb_uid = pw->pw_uid;
18540266059SGregory Neil Shapiro 	user->mbdb_gid = pw->pw_gid;
18640266059SGregory Neil Shapiro 	sm_pwfullname(pw->pw_gecos, pw->pw_name, user->mbdb_fullname,
18740266059SGregory Neil Shapiro 		      sizeof(user->mbdb_fullname));
18840266059SGregory Neil Shapiro 	(void) sm_strlcpy(user->mbdb_homedir, pw->pw_dir,
18940266059SGregory Neil Shapiro 			  sizeof(user->mbdb_homedir));
19040266059SGregory Neil Shapiro 	(void) sm_strlcpy(user->mbdb_shell, pw->pw_shell,
19140266059SGregory Neil Shapiro 			  sizeof(user->mbdb_shell));
19240266059SGregory Neil Shapiro }
19340266059SGregory Neil Shapiro 
19440266059SGregory Neil Shapiro /*
19540266059SGregory Neil Shapiro **  SM_PWFULLNAME -- build full name of user from pw_gecos field.
19640266059SGregory Neil Shapiro **
19740266059SGregory Neil Shapiro **	This routine interprets the strange entry that would appear
19840266059SGregory Neil Shapiro **	in the GECOS field of the password file.
19940266059SGregory Neil Shapiro **
20040266059SGregory Neil Shapiro **	Parameters:
20140266059SGregory Neil Shapiro **		gecos -- name to build.
20240266059SGregory Neil Shapiro **		user -- the login name of this user (for &).
20340266059SGregory Neil Shapiro **		buf -- place to put the result.
20440266059SGregory Neil Shapiro **		buflen -- length of buf.
20540266059SGregory Neil Shapiro **
20640266059SGregory Neil Shapiro **	Returns:
20740266059SGregory Neil Shapiro **		none.
20840266059SGregory Neil Shapiro */
20940266059SGregory Neil Shapiro 
21040266059SGregory Neil Shapiro void
21140266059SGregory Neil Shapiro sm_pwfullname(gecos, user, buf, buflen)
21240266059SGregory Neil Shapiro 	register char *gecos;
21340266059SGregory Neil Shapiro 	char *user;
21440266059SGregory Neil Shapiro 	char *buf;
21540266059SGregory Neil Shapiro 	size_t buflen;
21640266059SGregory Neil Shapiro {
21740266059SGregory Neil Shapiro 	register char *p;
21840266059SGregory Neil Shapiro 	register char *bp = buf;
21940266059SGregory Neil Shapiro 
22040266059SGregory Neil Shapiro 	if (*gecos == '*')
22140266059SGregory Neil Shapiro 		gecos++;
22240266059SGregory Neil Shapiro 
22340266059SGregory Neil Shapiro 	/* copy gecos, interpolating & to be full name */
22440266059SGregory Neil Shapiro 	for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
22540266059SGregory Neil Shapiro 	{
22640266059SGregory Neil Shapiro 		if (bp >= &buf[buflen - 1])
22740266059SGregory Neil Shapiro 		{
22840266059SGregory Neil Shapiro 			/* buffer overflow -- just use login name */
22940266059SGregory Neil Shapiro 			(void) sm_strlcpy(buf, user, buflen);
23040266059SGregory Neil Shapiro 			return;
23140266059SGregory Neil Shapiro 		}
23240266059SGregory Neil Shapiro 		if (*p == '&')
23340266059SGregory Neil Shapiro 		{
23440266059SGregory Neil Shapiro 			/* interpolate full name */
23540266059SGregory Neil Shapiro 			(void) sm_strlcpy(bp, user, buflen - (bp - buf));
23640266059SGregory Neil Shapiro 			*bp = toupper(*bp);
23740266059SGregory Neil Shapiro 			bp += strlen(bp);
23840266059SGregory Neil Shapiro 		}
23940266059SGregory Neil Shapiro 		else
24040266059SGregory Neil Shapiro 			*bp++ = *p;
24140266059SGregory Neil Shapiro 	}
24240266059SGregory Neil Shapiro 	*bp = '\0';
24340266059SGregory Neil Shapiro }
24440266059SGregory Neil Shapiro 
24540266059SGregory Neil Shapiro /*
24640266059SGregory Neil Shapiro **  /etc/passwd implementation.
24740266059SGregory Neil Shapiro */
24840266059SGregory Neil Shapiro 
24940266059SGregory Neil Shapiro /*
25040266059SGregory Neil Shapiro **  MBDB_PW_INITIALIZE -- initialize getpwnam() version
25140266059SGregory Neil Shapiro **
25240266059SGregory Neil Shapiro **	Parameters:
25340266059SGregory Neil Shapiro **		arg -- unused.
25440266059SGregory Neil Shapiro **
25540266059SGregory Neil Shapiro **	Results:
25640266059SGregory Neil Shapiro **		EX_OK.
25740266059SGregory Neil Shapiro */
25840266059SGregory Neil Shapiro 
25940266059SGregory Neil Shapiro /* ARGSUSED0 */
26040266059SGregory Neil Shapiro static int
26140266059SGregory Neil Shapiro mbdb_pw_initialize(arg)
26240266059SGregory Neil Shapiro 	char *arg;
26340266059SGregory Neil Shapiro {
26440266059SGregory Neil Shapiro 	return EX_OK;
26540266059SGregory Neil Shapiro }
26640266059SGregory Neil Shapiro 
26740266059SGregory Neil Shapiro /*
26840266059SGregory Neil Shapiro **  MBDB_PW_LOOKUP -- look up a local mail recipient, given name
26940266059SGregory Neil Shapiro **
27040266059SGregory Neil Shapiro **	Parameters:
27140266059SGregory Neil Shapiro **		name -- name of local mail recipient
27240266059SGregory Neil Shapiro **		user -- pointer to structure to fill in on success
27340266059SGregory Neil Shapiro **
27440266059SGregory Neil Shapiro **	Results:
27540266059SGregory Neil Shapiro **		On success, fill in *user and return EX_OK.
27640266059SGregory Neil Shapiro **		Failure: EX_NOUSER.
27740266059SGregory Neil Shapiro */
27840266059SGregory Neil Shapiro 
27940266059SGregory Neil Shapiro static int
28040266059SGregory Neil Shapiro mbdb_pw_lookup(name, user)
28140266059SGregory Neil Shapiro 	char *name;
28240266059SGregory Neil Shapiro 	SM_MBDB_T *user;
28340266059SGregory Neil Shapiro {
28440266059SGregory Neil Shapiro 	struct passwd *pw;
28540266059SGregory Neil Shapiro 
28640266059SGregory Neil Shapiro #ifdef HESIOD
28740266059SGregory Neil Shapiro 	/* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */
28840266059SGregory Neil Shapiro 	{
28940266059SGregory Neil Shapiro 		char *p;
29040266059SGregory Neil Shapiro 
29140266059SGregory Neil Shapiro 		for (p = name; *p != '\0'; p++)
29240266059SGregory Neil Shapiro 			if (!isascii(*p) || !isdigit(*p))
29340266059SGregory Neil Shapiro 				break;
29440266059SGregory Neil Shapiro 		if (*p == '\0')
29540266059SGregory Neil Shapiro 			return EX_NOUSER;
29640266059SGregory Neil Shapiro 	}
29740266059SGregory Neil Shapiro #endif /* HESIOD */
29840266059SGregory Neil Shapiro 
29940266059SGregory Neil Shapiro 	errno = 0;
30040266059SGregory Neil Shapiro 	pw = getpwnam(name);
30140266059SGregory Neil Shapiro 	if (pw == NULL)
30240266059SGregory Neil Shapiro 	{
30340266059SGregory Neil Shapiro #if 0
30440266059SGregory Neil Shapiro 		/*
30540266059SGregory Neil Shapiro 		**  getpwnam() isn't advertised as setting errno.
30640266059SGregory Neil Shapiro 		**  In fact, under FreeBSD, non-root getpwnam() on
30740266059SGregory Neil Shapiro 		**  non-existant users returns NULL with errno = EPERM.
30840266059SGregory Neil Shapiro 		**  This test won't work.
30940266059SGregory Neil Shapiro 		*/
31040266059SGregory Neil Shapiro 		switch (errno)
31140266059SGregory Neil Shapiro 		{
31240266059SGregory Neil Shapiro 		  case 0:
31340266059SGregory Neil Shapiro 			return EX_NOUSER;
31440266059SGregory Neil Shapiro 		  case EIO:
31540266059SGregory Neil Shapiro 			return EX_OSERR;
31640266059SGregory Neil Shapiro 		  default:
31740266059SGregory Neil Shapiro 			return EX_TEMPFAIL;
31840266059SGregory Neil Shapiro 		}
31940266059SGregory Neil Shapiro #endif /* 0 */
32040266059SGregory Neil Shapiro 		return EX_NOUSER;
32140266059SGregory Neil Shapiro 	}
32240266059SGregory Neil Shapiro 
32340266059SGregory Neil Shapiro 	sm_mbdb_frompw(user, pw);
32440266059SGregory Neil Shapiro 	return EX_OK;
32540266059SGregory Neil Shapiro }
32640266059SGregory Neil Shapiro 
32740266059SGregory Neil Shapiro /*
32840266059SGregory Neil Shapiro **  MBDB_PW_TERMINATE -- terminate connection to the mailbox database
32940266059SGregory Neil Shapiro **
33040266059SGregory Neil Shapiro **	Parameters:
33140266059SGregory Neil Shapiro **		none.
33240266059SGregory Neil Shapiro **
33340266059SGregory Neil Shapiro **	Results:
33440266059SGregory Neil Shapiro **		none.
33540266059SGregory Neil Shapiro */
33640266059SGregory Neil Shapiro 
33740266059SGregory Neil Shapiro static void
33840266059SGregory Neil Shapiro mbdb_pw_terminate()
33940266059SGregory Neil Shapiro {
34040266059SGregory Neil Shapiro 	endpwent();
34140266059SGregory Neil Shapiro }
34240266059SGregory Neil Shapiro 
34340266059SGregory Neil Shapiro #if LDAPMAP
34440266059SGregory Neil Shapiro # if _LDAP_EXAMPLE_
34540266059SGregory Neil Shapiro /*
34640266059SGregory Neil Shapiro **  LDAP example implementation based on RFC 2307, "An Approach for Using
34740266059SGregory Neil Shapiro **  LDAP as a Network Information Service":
34840266059SGregory Neil Shapiro **
34940266059SGregory Neil Shapiro **	( nisSchema.1.0 NAME 'uidNumber'
35040266059SGregory Neil Shapiro **	  DESC 'An integer uniquely identifying a user in an
35140266059SGregory Neil Shapiro **		administrative domain'
35240266059SGregory Neil Shapiro **	  EQUALITY integerMatch SYNTAX 'INTEGER' SINGLE-VALUE )
35340266059SGregory Neil Shapiro **
35440266059SGregory Neil Shapiro **	( nisSchema.1.1 NAME 'gidNumber'
35540266059SGregory Neil Shapiro **	  DESC 'An integer uniquely identifying a group in an
35640266059SGregory Neil Shapiro **		administrative domain'
35740266059SGregory Neil Shapiro **	  EQUALITY integerMatch SYNTAX 'INTEGER' SINGLE-VALUE )
35840266059SGregory Neil Shapiro **
35940266059SGregory Neil Shapiro **	( nisSchema.1.2 NAME 'gecos'
36040266059SGregory Neil Shapiro **	  DESC 'The GECOS field; the common name'
36140266059SGregory Neil Shapiro **	  EQUALITY caseIgnoreIA5Match
36240266059SGregory Neil Shapiro **	  SUBSTRINGS caseIgnoreIA5SubstringsMatch
36340266059SGregory Neil Shapiro **	  SYNTAX 'IA5String' SINGLE-VALUE )
36440266059SGregory Neil Shapiro **
36540266059SGregory Neil Shapiro **	( nisSchema.1.3 NAME 'homeDirectory'
36640266059SGregory Neil Shapiro **	  DESC 'The absolute path to the home directory'
36740266059SGregory Neil Shapiro **	  EQUALITY caseExactIA5Match
36840266059SGregory Neil Shapiro **	  SYNTAX 'IA5String' SINGLE-VALUE )
36940266059SGregory Neil Shapiro **
37040266059SGregory Neil Shapiro **	( nisSchema.1.4 NAME 'loginShell'
37140266059SGregory Neil Shapiro **	  DESC 'The path to the login shell'
37240266059SGregory Neil Shapiro **	  EQUALITY caseExactIA5Match
37340266059SGregory Neil Shapiro **	  SYNTAX 'IA5String' SINGLE-VALUE )
37440266059SGregory Neil Shapiro **
37540266059SGregory Neil Shapiro **	( nisSchema.2.0 NAME 'posixAccount' SUP top AUXILIARY
37640266059SGregory Neil Shapiro **	  DESC 'Abstraction of an account with POSIX attributes'
37740266059SGregory Neil Shapiro **	  MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
37840266059SGregory Neil Shapiro **	  MAY ( userPassword $ loginShell $ gecos $ description ) )
37940266059SGregory Neil Shapiro **
38040266059SGregory Neil Shapiro */
38140266059SGregory Neil Shapiro 
38240266059SGregory Neil Shapiro #  define MBDB_LDAP_LABEL		"MailboxDatabase"
38340266059SGregory Neil Shapiro 
38440266059SGregory Neil Shapiro #  ifndef MBDB_LDAP_FILTER
38540266059SGregory Neil Shapiro #   define MBDB_LDAP_FILTER		"(&(objectClass=posixAccount)(uid=%0))"
38640266059SGregory Neil Shapiro #  endif /* MBDB_LDAP_FILTER */
38740266059SGregory Neil Shapiro 
38840266059SGregory Neil Shapiro #  ifndef MBDB_DEFAULT_LDAP_BASEDN
38940266059SGregory Neil Shapiro #   define MBDB_DEFAULT_LDAP_BASEDN	NULL
39040266059SGregory Neil Shapiro #  endif /* MBDB_DEFAULT_LDAP_BASEDN */
39140266059SGregory Neil Shapiro 
39240266059SGregory Neil Shapiro #  ifndef MBDB_DEFAULT_LDAP_SERVER
39340266059SGregory Neil Shapiro #   define MBDB_DEFAULT_LDAP_SERVER	NULL
39440266059SGregory Neil Shapiro #  endif /* MBDB_DEFAULT_LDAP_SERVER */
39540266059SGregory Neil Shapiro 
39640266059SGregory Neil Shapiro /*
39740266059SGregory Neil Shapiro **  MBDB_LDAP_INITIALIZE -- initialize LDAP version
39840266059SGregory Neil Shapiro **
39940266059SGregory Neil Shapiro **	Parameters:
40040266059SGregory Neil Shapiro **		arg -- LDAP specification
40140266059SGregory Neil Shapiro **
40240266059SGregory Neil Shapiro **	Results:
40340266059SGregory Neil Shapiro **		EX_OK on success, or an EX_* code on failure.
40440266059SGregory Neil Shapiro */
40540266059SGregory Neil Shapiro 
40640266059SGregory Neil Shapiro static int
40740266059SGregory Neil Shapiro mbdb_ldap_initialize(arg)
40840266059SGregory Neil Shapiro 	char *arg;
40940266059SGregory Neil Shapiro {
41040266059SGregory Neil Shapiro 	sm_ldap_clear(&LDAPLMAP);
41140266059SGregory Neil Shapiro 	LDAPLMAP.ldap_base = MBDB_DEFAULT_LDAP_BASEDN;
41240266059SGregory Neil Shapiro 	LDAPLMAP.ldap_host = MBDB_DEFAULT_LDAP_SERVER;
41340266059SGregory Neil Shapiro 	LDAPLMAP.ldap_filter = MBDB_LDAP_FILTER;
41440266059SGregory Neil Shapiro 
41540266059SGregory Neil Shapiro 	/* Only want one match */
41640266059SGregory Neil Shapiro 	LDAPLMAP.ldap_sizelimit = 1;
41740266059SGregory Neil Shapiro 
41840266059SGregory Neil Shapiro 	/* interpolate new ldap_base and ldap_host from arg if given */
41940266059SGregory Neil Shapiro 	if (arg != NULL && *arg != '\0')
42040266059SGregory Neil Shapiro 	{
42140266059SGregory Neil Shapiro 		char *new;
42240266059SGregory Neil Shapiro 		char *sep;
42340266059SGregory Neil Shapiro 		size_t len;
42440266059SGregory Neil Shapiro 
42540266059SGregory Neil Shapiro 		len = strlen(arg) + 1;
42640266059SGregory Neil Shapiro 		new = sm_malloc(len);
42740266059SGregory Neil Shapiro 		if (new == NULL)
42840266059SGregory Neil Shapiro 			return EX_TEMPFAIL;
42940266059SGregory Neil Shapiro 		(void) sm_strlcpy(new, arg, len);
43040266059SGregory Neil Shapiro 		sep = strrchr(new, '@');
43140266059SGregory Neil Shapiro 		if (sep != NULL)
43240266059SGregory Neil Shapiro 		{
43340266059SGregory Neil Shapiro 			*sep++ = '\0';
43440266059SGregory Neil Shapiro 			LDAPLMAP.ldap_host = sep;
43540266059SGregory Neil Shapiro 		}
43640266059SGregory Neil Shapiro 		LDAPLMAP.ldap_base = new;
43740266059SGregory Neil Shapiro 	}
43840266059SGregory Neil Shapiro 
43940266059SGregory Neil Shapiro 	/* No connection yet, connect */
44040266059SGregory Neil Shapiro 	if (!sm_ldap_start(MBDB_LDAP_LABEL, &LDAPLMAP))
44140266059SGregory Neil Shapiro 		return EX_UNAVAILABLE;
44240266059SGregory Neil Shapiro 	return EX_OK;
44340266059SGregory Neil Shapiro }
44440266059SGregory Neil Shapiro 
44540266059SGregory Neil Shapiro 
44640266059SGregory Neil Shapiro /*
44740266059SGregory Neil Shapiro **  MBDB_LDAP_LOOKUP -- look up a local mail recipient, given name
44840266059SGregory Neil Shapiro **
44940266059SGregory Neil Shapiro **	Parameters:
45040266059SGregory Neil Shapiro **		name -- name of local mail recipient
45140266059SGregory Neil Shapiro **		user -- pointer to structure to fill in on success
45240266059SGregory Neil Shapiro **
45340266059SGregory Neil Shapiro **	Results:
45440266059SGregory Neil Shapiro **		On success, fill in *user and return EX_OK.
45540266059SGregory Neil Shapiro **		Failure: EX_NOUSER.
45640266059SGregory Neil Shapiro */
45740266059SGregory Neil Shapiro 
45840266059SGregory Neil Shapiro #define NEED_FULLNAME	0x01
45940266059SGregory Neil Shapiro #define NEED_HOMEDIR	0x02
46040266059SGregory Neil Shapiro #define NEED_SHELL	0x04
46140266059SGregory Neil Shapiro #define NEED_UID	0x08
46240266059SGregory Neil Shapiro #define NEED_GID	0x10
46340266059SGregory Neil Shapiro 
46440266059SGregory Neil Shapiro static int
46540266059SGregory Neil Shapiro mbdb_ldap_lookup(name, user)
46640266059SGregory Neil Shapiro 	char *name;
46740266059SGregory Neil Shapiro 	SM_MBDB_T *user;
46840266059SGregory Neil Shapiro {
46940266059SGregory Neil Shapiro 	int msgid;
47040266059SGregory Neil Shapiro 	int need;
47140266059SGregory Neil Shapiro 	int ret;
47240266059SGregory Neil Shapiro 	int save_errno;
47340266059SGregory Neil Shapiro 	LDAPMessage *entry;
47440266059SGregory Neil Shapiro 	BerElement *ber;
47540266059SGregory Neil Shapiro 	char *attr = NULL;
47640266059SGregory Neil Shapiro 
47740266059SGregory Neil Shapiro 	if (strlen(name) >= sizeof(user->mbdb_name))
47840266059SGregory Neil Shapiro 	{
47940266059SGregory Neil Shapiro 		errno = EINVAL;
48040266059SGregory Neil Shapiro 		return EX_NOUSER;
48140266059SGregory Neil Shapiro 	}
48240266059SGregory Neil Shapiro 
48340266059SGregory Neil Shapiro 	if (LDAPLMAP.ldap_filter == NULL)
48440266059SGregory Neil Shapiro 	{
48540266059SGregory Neil Shapiro 		/* map not initialized, but don't have arg here */
48640266059SGregory Neil Shapiro 		errno = EFAULT;
48740266059SGregory Neil Shapiro 		return EX_TEMPFAIL;
48840266059SGregory Neil Shapiro 	}
48940266059SGregory Neil Shapiro 
49040266059SGregory Neil Shapiro 	if (LDAPLMAP.ldap_ld == NULL)
49140266059SGregory Neil Shapiro 	{
49240266059SGregory Neil Shapiro 		/* map not open, try to open now */
49340266059SGregory Neil Shapiro 		if (!sm_ldap_start(MBDB_LDAP_LABEL, &LDAPLMAP))
49440266059SGregory Neil Shapiro 			return EX_TEMPFAIL;
49540266059SGregory Neil Shapiro 	}
49640266059SGregory Neil Shapiro 
49740266059SGregory Neil Shapiro 	sm_ldap_setopts(LDAPLMAP.ldap_ld, &LDAPLMAP);
49840266059SGregory Neil Shapiro 	msgid = sm_ldap_search(&LDAPLMAP, name);
49940266059SGregory Neil Shapiro 	if (msgid == -1)
50040266059SGregory Neil Shapiro 	{
50140266059SGregory Neil Shapiro 		save_errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld) + E_LDAPBASE;
50240266059SGregory Neil Shapiro #  ifdef LDAP_SERVER_DOWN
50340266059SGregory Neil Shapiro 		if (errno == LDAP_SERVER_DOWN)
50440266059SGregory Neil Shapiro 		{
50540266059SGregory Neil Shapiro 			/* server disappeared, try reopen on next search */
50640266059SGregory Neil Shapiro 			sm_ldap_close(&LDAPLMAP);
50740266059SGregory Neil Shapiro 		}
50840266059SGregory Neil Shapiro #  endif /* LDAP_SERVER_DOWN */
50940266059SGregory Neil Shapiro 		errno = save_errno;
51040266059SGregory Neil Shapiro 		return EX_TEMPFAIL;
51140266059SGregory Neil Shapiro 	}
51240266059SGregory Neil Shapiro 
51340266059SGregory Neil Shapiro 	/* Get results */
51440266059SGregory Neil Shapiro 	ret = ldap_result(LDAPLMAP.ldap_ld, msgid, 1,
51540266059SGregory Neil Shapiro 			  (LDAPLMAP.ldap_timeout.tv_sec == 0 ? NULL :
51640266059SGregory Neil Shapiro 			   &(LDAPLMAP.ldap_timeout)),
51740266059SGregory Neil Shapiro 			  &(LDAPLMAP.ldap_res));
51840266059SGregory Neil Shapiro 
51940266059SGregory Neil Shapiro 	if (ret != LDAP_RES_SEARCH_RESULT &&
52040266059SGregory Neil Shapiro 	    ret != LDAP_RES_SEARCH_ENTRY)
52140266059SGregory Neil Shapiro 	{
52240266059SGregory Neil Shapiro 		if (ret == 0)
52340266059SGregory Neil Shapiro 			errno = ETIMEDOUT;
52440266059SGregory Neil Shapiro 		else
52540266059SGregory Neil Shapiro 			errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld);
52640266059SGregory Neil Shapiro 		ret = EX_TEMPFAIL;
52740266059SGregory Neil Shapiro 		goto abort;
52840266059SGregory Neil Shapiro 	}
52940266059SGregory Neil Shapiro 
53040266059SGregory Neil Shapiro 	entry = ldap_first_entry(LDAPLMAP.ldap_ld, LDAPLMAP.ldap_res);
53140266059SGregory Neil Shapiro 	if (entry == NULL)
53240266059SGregory Neil Shapiro 	{
53340266059SGregory Neil Shapiro 		save_errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld);
53440266059SGregory Neil Shapiro 		if (save_errno == LDAP_SUCCESS)
53540266059SGregory Neil Shapiro 		{
53640266059SGregory Neil Shapiro 			errno = ENOENT;
53740266059SGregory Neil Shapiro 			ret = EX_NOUSER;
53840266059SGregory Neil Shapiro 		}
53940266059SGregory Neil Shapiro 		else
54040266059SGregory Neil Shapiro 		{
54140266059SGregory Neil Shapiro 			errno = save_errno;
54240266059SGregory Neil Shapiro 			ret = EX_TEMPFAIL;
54340266059SGregory Neil Shapiro 		}
54440266059SGregory Neil Shapiro 		goto abort;
54540266059SGregory Neil Shapiro 	}
54640266059SGregory Neil Shapiro 
54740266059SGregory Neil Shapiro # if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
54840266059SGregory Neil Shapiro 	/*
54940266059SGregory Neil Shapiro 	**  Reset value to prevent lingering
55040266059SGregory Neil Shapiro 	**  LDAP_DECODING_ERROR due to
55140266059SGregory Neil Shapiro 	**  OpenLDAP 1.X's hack (see below)
55240266059SGregory Neil Shapiro 	*/
55340266059SGregory Neil Shapiro 
55440266059SGregory Neil Shapiro 	LDAPLMAP.ldap_ld->ld_errno = LDAP_SUCCESS;
55540266059SGregory Neil Shapiro # endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
55640266059SGregory Neil Shapiro 
55740266059SGregory Neil Shapiro 	ret = EX_OK;
55840266059SGregory Neil Shapiro 	need = NEED_FULLNAME|NEED_HOMEDIR|NEED_SHELL|NEED_UID|NEED_GID;
55940266059SGregory Neil Shapiro 	for (attr = ldap_first_attribute(LDAPLMAP.ldap_ld, entry, &ber);
56040266059SGregory Neil Shapiro 	     attr != NULL;
56140266059SGregory Neil Shapiro 	     attr = ldap_next_attribute(LDAPLMAP.ldap_ld, entry, ber))
56240266059SGregory Neil Shapiro 	{
56340266059SGregory Neil Shapiro 		char **vals;
56440266059SGregory Neil Shapiro 
56540266059SGregory Neil Shapiro 		vals = ldap_get_values(LDAPLMAP.ldap_ld, entry, attr);
56640266059SGregory Neil Shapiro 		if (vals == NULL)
56740266059SGregory Neil Shapiro 		{
56840266059SGregory Neil Shapiro 			errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld);
56940266059SGregory Neil Shapiro 			if (errno == LDAP_SUCCESS)
57040266059SGregory Neil Shapiro 			{
57140266059SGregory Neil Shapiro # if USING_NETSCAPE_LDAP
57240266059SGregory Neil Shapiro 				ldap_memfree(attr);
57340266059SGregory Neil Shapiro # endif /* USING_NETSCAPE_LDAP */
57440266059SGregory Neil Shapiro 				continue;
57540266059SGregory Neil Shapiro 			}
57640266059SGregory Neil Shapiro 
57740266059SGregory Neil Shapiro 			/* Must be an error */
57840266059SGregory Neil Shapiro 			errno += E_LDAPBASE;
57940266059SGregory Neil Shapiro 			ret = EX_TEMPFAIL;
58040266059SGregory Neil Shapiro 			goto abort;
58140266059SGregory Neil Shapiro 		}
58240266059SGregory Neil Shapiro 
58340266059SGregory Neil Shapiro # if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
58440266059SGregory Neil Shapiro 		/*
58540266059SGregory Neil Shapiro 		**  Reset value to prevent lingering
58640266059SGregory Neil Shapiro 		**  LDAP_DECODING_ERROR due to
58740266059SGregory Neil Shapiro 		**  OpenLDAP 1.X's hack (see below)
58840266059SGregory Neil Shapiro 		*/
58940266059SGregory Neil Shapiro 
59040266059SGregory Neil Shapiro 		LDAPLMAP.ldap_ld->ld_errno = LDAP_SUCCESS;
59140266059SGregory Neil Shapiro # endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
59240266059SGregory Neil Shapiro 
59340266059SGregory Neil Shapiro 		if (vals[0] == NULL || vals[0][0] == '\0')
59440266059SGregory Neil Shapiro 			goto skip;
59540266059SGregory Neil Shapiro 
59640266059SGregory Neil Shapiro 		if (strcasecmp(attr, "gecos") == 0)
59740266059SGregory Neil Shapiro 		{
59840266059SGregory Neil Shapiro 			if (!bitset(NEED_FULLNAME, need) ||
59940266059SGregory Neil Shapiro 			    strlen(vals[0]) >= sizeof(user->mbdb_fullname))
60040266059SGregory Neil Shapiro 				goto skip;
60140266059SGregory Neil Shapiro 
60240266059SGregory Neil Shapiro 			sm_pwfullname(vals[0], name, user->mbdb_fullname,
60340266059SGregory Neil Shapiro 				      sizeof(user->mbdb_fullname));
60440266059SGregory Neil Shapiro 			need &= ~NEED_FULLNAME;
60540266059SGregory Neil Shapiro 		}
60640266059SGregory Neil Shapiro 		else if (strcasecmp(attr, "homeDirectory") == 0)
60740266059SGregory Neil Shapiro 		{
60840266059SGregory Neil Shapiro 			if (!bitset(NEED_HOMEDIR, need) ||
60940266059SGregory Neil Shapiro 			    strlen(vals[0]) >= sizeof(user->mbdb_homedir))
61040266059SGregory Neil Shapiro 				goto skip;
61140266059SGregory Neil Shapiro 
61240266059SGregory Neil Shapiro 			(void) sm_strlcpy(user->mbdb_homedir, vals[0],
61340266059SGregory Neil Shapiro 					  sizeof(user->mbdb_homedir));
61440266059SGregory Neil Shapiro 			need &= ~NEED_HOMEDIR;
61540266059SGregory Neil Shapiro 		}
61640266059SGregory Neil Shapiro 		else if (strcasecmp(attr, "loginShell") == 0)
61740266059SGregory Neil Shapiro 		{
61840266059SGregory Neil Shapiro 			if (!bitset(NEED_SHELL, need) ||
61940266059SGregory Neil Shapiro 			    strlen(vals[0]) >= sizeof(user->mbdb_shell))
62040266059SGregory Neil Shapiro 				goto skip;
62140266059SGregory Neil Shapiro 
62240266059SGregory Neil Shapiro 			(void) sm_strlcpy(user->mbdb_shell, vals[0],
62340266059SGregory Neil Shapiro 					  sizeof(user->mbdb_shell));
62440266059SGregory Neil Shapiro 			need &= ~NEED_SHELL;
62540266059SGregory Neil Shapiro 		}
62640266059SGregory Neil Shapiro 		else if (strcasecmp(attr, "uidNumber") == 0)
62740266059SGregory Neil Shapiro 		{
62840266059SGregory Neil Shapiro 			char *p;
62940266059SGregory Neil Shapiro 
63040266059SGregory Neil Shapiro 			if (!bitset(NEED_UID, need))
63140266059SGregory Neil Shapiro 				goto skip;
63240266059SGregory Neil Shapiro 
63340266059SGregory Neil Shapiro 			for (p = vals[0]; *p != '\0'; p++)
63440266059SGregory Neil Shapiro 			{
63540266059SGregory Neil Shapiro 				/* allow negative numbers */
63640266059SGregory Neil Shapiro 				if (p == vals[0] && *p == '-')
63740266059SGregory Neil Shapiro 				{
63840266059SGregory Neil Shapiro 					/* but not simply '-' */
63940266059SGregory Neil Shapiro 					if (*(p + 1) == '\0')
64040266059SGregory Neil Shapiro 						goto skip;
64140266059SGregory Neil Shapiro 				}
64240266059SGregory Neil Shapiro 				else if (!isascii(*p) || !isdigit(*p))
64340266059SGregory Neil Shapiro 					goto skip;
64440266059SGregory Neil Shapiro 			}
64540266059SGregory Neil Shapiro 			user->mbdb_uid = atoi(vals[0]);
64640266059SGregory Neil Shapiro 			need &= ~NEED_UID;
64740266059SGregory Neil Shapiro 		}
64840266059SGregory Neil Shapiro 		else if (strcasecmp(attr, "gidNumber") == 0)
64940266059SGregory Neil Shapiro 		{
65040266059SGregory Neil Shapiro 			char *p;
65140266059SGregory Neil Shapiro 
65240266059SGregory Neil Shapiro 			if (!bitset(NEED_GID, need))
65340266059SGregory Neil Shapiro 				goto skip;
65440266059SGregory Neil Shapiro 
65540266059SGregory Neil Shapiro 			for (p = vals[0]; *p != '\0'; p++)
65640266059SGregory Neil Shapiro 			{
65740266059SGregory Neil Shapiro 				/* allow negative numbers */
65840266059SGregory Neil Shapiro 				if (p == vals[0] && *p == '-')
65940266059SGregory Neil Shapiro 				{
66040266059SGregory Neil Shapiro 					/* but not simply '-' */
66140266059SGregory Neil Shapiro 					if (*(p + 1) == '\0')
66240266059SGregory Neil Shapiro 						goto skip;
66340266059SGregory Neil Shapiro 				}
66440266059SGregory Neil Shapiro 				else if (!isascii(*p) || !isdigit(*p))
66540266059SGregory Neil Shapiro 					goto skip;
66640266059SGregory Neil Shapiro 			}
66740266059SGregory Neil Shapiro 			user->mbdb_gid = atoi(vals[0]);
66840266059SGregory Neil Shapiro 			need &= ~NEED_GID;
66940266059SGregory Neil Shapiro 		}
67040266059SGregory Neil Shapiro 
67140266059SGregory Neil Shapiro skip:
67240266059SGregory Neil Shapiro 		ldap_value_free(vals);
67340266059SGregory Neil Shapiro # if USING_NETSCAPE_LDAP
67440266059SGregory Neil Shapiro 		ldap_memfree(attr);
67540266059SGregory Neil Shapiro # endif /* USING_NETSCAPE_LDAP */
67640266059SGregory Neil Shapiro 	}
67740266059SGregory Neil Shapiro 
67840266059SGregory Neil Shapiro 	errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld);
67940266059SGregory Neil Shapiro 
68040266059SGregory Neil Shapiro 	/*
68140266059SGregory Neil Shapiro 	**  We check errno != LDAP_DECODING_ERROR since
68240266059SGregory Neil Shapiro 	**  OpenLDAP 1.X has a very ugly *undocumented*
68340266059SGregory Neil Shapiro 	**  hack of returning this error code from
68440266059SGregory Neil Shapiro 	**  ldap_next_attribute() if the library freed the
68540266059SGregory Neil Shapiro 	**  ber attribute.  See:
68640266059SGregory Neil Shapiro 	**  http://www.openldap.org/lists/openldap-devel/9901/msg00064.html
68740266059SGregory Neil Shapiro 	*/
68840266059SGregory Neil Shapiro 
68940266059SGregory Neil Shapiro 	if (errno != LDAP_SUCCESS &&
69040266059SGregory Neil Shapiro 	    errno != LDAP_DECODING_ERROR)
69140266059SGregory Neil Shapiro 	{
69240266059SGregory Neil Shapiro 		/* Must be an error */
69340266059SGregory Neil Shapiro 		errno += E_LDAPBASE;
69440266059SGregory Neil Shapiro 		ret = EX_TEMPFAIL;
69540266059SGregory Neil Shapiro 		goto abort;
69640266059SGregory Neil Shapiro 	}
69740266059SGregory Neil Shapiro 
69840266059SGregory Neil Shapiro  abort:
69940266059SGregory Neil Shapiro 	save_errno = errno;
70040266059SGregory Neil Shapiro 	if (attr != NULL)
70140266059SGregory Neil Shapiro 	{
70240266059SGregory Neil Shapiro # if USING_NETSCAPE_LDAP
70340266059SGregory Neil Shapiro 		ldap_memfree(attr);
70440266059SGregory Neil Shapiro # endif /* USING_NETSCAPE_LDAP */
70540266059SGregory Neil Shapiro 		attr = NULL;
70640266059SGregory Neil Shapiro 	}
70740266059SGregory Neil Shapiro 	if (LDAPLMAP.ldap_res != NULL)
70840266059SGregory Neil Shapiro 	{
70940266059SGregory Neil Shapiro 		ldap_msgfree(LDAPLMAP.ldap_res);
71040266059SGregory Neil Shapiro 		LDAPLMAP.ldap_res = NULL;
71140266059SGregory Neil Shapiro 	}
71240266059SGregory Neil Shapiro 	if (ret == EX_OK)
71340266059SGregory Neil Shapiro 	{
71440266059SGregory Neil Shapiro 		if (need == 0)
71540266059SGregory Neil Shapiro 		{
71640266059SGregory Neil Shapiro 			(void) sm_strlcpy(user->mbdb_name, name,
71740266059SGregory Neil Shapiro 					  sizeof(user->mbdb_name));
71840266059SGregory Neil Shapiro 			save_errno = 0;
71940266059SGregory Neil Shapiro 		}
72040266059SGregory Neil Shapiro 		else
72140266059SGregory Neil Shapiro 		{
72240266059SGregory Neil Shapiro 			ret = EX_NOUSER;
72340266059SGregory Neil Shapiro 			save_errno = EINVAL;
72440266059SGregory Neil Shapiro 		}
72540266059SGregory Neil Shapiro 	}
72640266059SGregory Neil Shapiro 	errno = save_errno;
72740266059SGregory Neil Shapiro 	return ret;
72840266059SGregory Neil Shapiro }
72940266059SGregory Neil Shapiro 
73040266059SGregory Neil Shapiro /*
73140266059SGregory Neil Shapiro **  MBDB_LDAP_TERMINATE -- terminate connection to the mailbox database
73240266059SGregory Neil Shapiro **
73340266059SGregory Neil Shapiro **	Parameters:
73440266059SGregory Neil Shapiro **		none.
73540266059SGregory Neil Shapiro **
73640266059SGregory Neil Shapiro **	Results:
73740266059SGregory Neil Shapiro **		none.
73840266059SGregory Neil Shapiro */
73940266059SGregory Neil Shapiro 
74040266059SGregory Neil Shapiro static void
74140266059SGregory Neil Shapiro mbdb_ldap_terminate()
74240266059SGregory Neil Shapiro {
74340266059SGregory Neil Shapiro 	sm_ldap_close(&LDAPLMAP);
74440266059SGregory Neil Shapiro }
74540266059SGregory Neil Shapiro # endif /* _LDAP_EXAMPLE_ */
74640266059SGregory Neil Shapiro #endif /* LDAPMAP */
747