140266059SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro * Copyright (c) 2001-2003,2009 Proofpoint, 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>
114313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: mbdb.c,v 1.43 2014-01-08 17:03:15 ca 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>
2013bd1963SGregory Neil Shapiro #include <unistd.h>
2140266059SGregory Neil Shapiro
2240266059SGregory Neil Shapiro #include <sm/limits.h>
2340266059SGregory Neil Shapiro #include <sm/conf.h>
2440266059SGregory Neil Shapiro #include <sm/assert.h>
2540266059SGregory Neil Shapiro #include <sm/bitops.h>
2640266059SGregory Neil Shapiro #include <sm/errstring.h>
2740266059SGregory Neil Shapiro #include <sm/heap.h>
2840266059SGregory Neil Shapiro #include <sm/mbdb.h>
2940266059SGregory Neil Shapiro #include <sm/string.h>
3040266059SGregory Neil Shapiro #include <sm/sysexits.h>
3140266059SGregory Neil Shapiro
32*2fb4f839SGregory Neil Shapiro #if LDAPMAP && _LDAP_EXAMPLE_
3340266059SGregory Neil Shapiro # include <sm/ldap.h>
345b0945b5SGregory Neil Shapiro #endif
3540266059SGregory Neil Shapiro
3640266059SGregory Neil Shapiro typedef struct
3740266059SGregory Neil Shapiro {
3840266059SGregory Neil Shapiro char *mbdb_typename;
3940266059SGregory Neil Shapiro int (*mbdb_initialize) __P((char *));
4040266059SGregory Neil Shapiro int (*mbdb_lookup) __P((char *name, SM_MBDB_T *user));
4140266059SGregory Neil Shapiro void (*mbdb_terminate) __P((void));
4240266059SGregory Neil Shapiro } SM_MBDB_TYPE_T;
4340266059SGregory Neil Shapiro
4440266059SGregory Neil Shapiro static int mbdb_pw_initialize __P((char *));
4540266059SGregory Neil Shapiro static int mbdb_pw_lookup __P((char *name, SM_MBDB_T *user));
4640266059SGregory Neil Shapiro static void mbdb_pw_terminate __P((void));
4740266059SGregory Neil Shapiro
48*2fb4f839SGregory Neil Shapiro #if LDAPMAP && _LDAP_EXAMPLE_
4940266059SGregory Neil Shapiro static struct sm_ldap_struct LDAPLMAP;
5040266059SGregory Neil Shapiro static int mbdb_ldap_initialize __P((char *));
5140266059SGregory Neil Shapiro static int mbdb_ldap_lookup __P((char *name, SM_MBDB_T *user));
5240266059SGregory Neil Shapiro static void mbdb_ldap_terminate __P((void));
53*2fb4f839SGregory Neil Shapiro #endif /* LDAPMAP && _LDAP_EXAMPLE_ */
5440266059SGregory Neil Shapiro
5540266059SGregory Neil Shapiro static SM_MBDB_TYPE_T SmMbdbTypes[] =
5640266059SGregory Neil Shapiro {
5740266059SGregory Neil Shapiro { "pw", mbdb_pw_initialize, mbdb_pw_lookup, mbdb_pw_terminate },
58*2fb4f839SGregory Neil Shapiro #if LDAPMAP && _LDAP_EXAMPLE_
5940266059SGregory Neil Shapiro { "ldap", mbdb_ldap_initialize, mbdb_ldap_lookup, mbdb_ldap_terminate },
605b0945b5SGregory Neil Shapiro #endif
6140266059SGregory Neil Shapiro { NULL, NULL, NULL, NULL }
6240266059SGregory Neil Shapiro };
6340266059SGregory Neil Shapiro
6440266059SGregory Neil Shapiro static SM_MBDB_TYPE_T *SmMbdbType = &SmMbdbTypes[0];
6540266059SGregory Neil Shapiro
6640266059SGregory Neil Shapiro /*
6740266059SGregory Neil Shapiro ** SM_MBDB_INITIALIZE -- specify which mailbox database to use
6840266059SGregory Neil Shapiro **
6940266059SGregory Neil Shapiro ** If this function is not called, then the "pw" implementation
7040266059SGregory Neil Shapiro ** is used by default; this implementation uses getpwnam().
7140266059SGregory Neil Shapiro **
7240266059SGregory Neil Shapiro ** Parameters:
7340266059SGregory Neil Shapiro ** mbdb -- Which mailbox database to use.
7440266059SGregory Neil Shapiro ** The argument has the form "name" or "name.arg".
7540266059SGregory Neil Shapiro ** "pw" means use getpwnam().
7640266059SGregory Neil Shapiro **
7740266059SGregory Neil Shapiro ** Results:
7840266059SGregory Neil Shapiro ** EX_OK on success, or an EX_* code on failure.
7940266059SGregory Neil Shapiro */
8040266059SGregory Neil Shapiro
8140266059SGregory Neil Shapiro int
sm_mbdb_initialize(mbdb)8240266059SGregory Neil Shapiro sm_mbdb_initialize(mbdb)
8340266059SGregory Neil Shapiro char *mbdb;
8440266059SGregory Neil Shapiro {
8540266059SGregory Neil Shapiro size_t namelen;
8640266059SGregory Neil Shapiro int err;
8740266059SGregory Neil Shapiro char *name;
8840266059SGregory Neil Shapiro char *arg;
8940266059SGregory Neil Shapiro SM_MBDB_TYPE_T *t;
9040266059SGregory Neil Shapiro
9140266059SGregory Neil Shapiro SM_REQUIRE(mbdb != NULL);
9240266059SGregory Neil Shapiro
9340266059SGregory Neil Shapiro name = mbdb;
9440266059SGregory Neil Shapiro arg = strchr(mbdb, '.');
9540266059SGregory Neil Shapiro if (arg == NULL)
9640266059SGregory Neil Shapiro namelen = strlen(name);
9740266059SGregory Neil Shapiro else
9840266059SGregory Neil Shapiro {
9940266059SGregory Neil Shapiro namelen = arg - name;
10040266059SGregory Neil Shapiro ++arg;
10140266059SGregory Neil Shapiro }
10240266059SGregory Neil Shapiro
10340266059SGregory Neil Shapiro for (t = SmMbdbTypes; t->mbdb_typename != NULL; ++t)
10440266059SGregory Neil Shapiro {
10540266059SGregory Neil Shapiro if (strlen(t->mbdb_typename) == namelen &&
10640266059SGregory Neil Shapiro strncmp(name, t->mbdb_typename, namelen) == 0)
10740266059SGregory Neil Shapiro {
10894c01205SGregory Neil Shapiro err = EX_OK;
10994c01205SGregory Neil Shapiro if (t->mbdb_initialize != NULL)
11040266059SGregory Neil Shapiro err = t->mbdb_initialize(arg);
11140266059SGregory Neil Shapiro if (err == EX_OK)
11240266059SGregory Neil Shapiro SmMbdbType = t;
11340266059SGregory Neil Shapiro return err;
11440266059SGregory Neil Shapiro }
11540266059SGregory Neil Shapiro }
11640266059SGregory Neil Shapiro return EX_UNAVAILABLE;
11740266059SGregory Neil Shapiro }
11840266059SGregory Neil Shapiro
11940266059SGregory Neil Shapiro /*
12040266059SGregory Neil Shapiro ** SM_MBDB_TERMINATE -- terminate connection to the mailbox database
12140266059SGregory Neil Shapiro **
12240266059SGregory Neil Shapiro ** Because this function closes any cached file descriptors that
12340266059SGregory Neil Shapiro ** are being held open for the connection to the mailbox database,
12440266059SGregory Neil Shapiro ** it should be called for security reasons prior to dropping privileges
12540266059SGregory Neil Shapiro ** and execing another process.
12640266059SGregory Neil Shapiro **
12740266059SGregory Neil Shapiro ** Parameters:
12840266059SGregory Neil Shapiro ** none.
12940266059SGregory Neil Shapiro **
13040266059SGregory Neil Shapiro ** Results:
13140266059SGregory Neil Shapiro ** none.
13240266059SGregory Neil Shapiro */
13340266059SGregory Neil Shapiro
13440266059SGregory Neil Shapiro void
sm_mbdb_terminate()13540266059SGregory Neil Shapiro sm_mbdb_terminate()
13640266059SGregory Neil Shapiro {
13794c01205SGregory Neil Shapiro if (SmMbdbType->mbdb_terminate != NULL)
13840266059SGregory Neil Shapiro SmMbdbType->mbdb_terminate();
13940266059SGregory Neil Shapiro }
14040266059SGregory Neil Shapiro
14140266059SGregory Neil Shapiro /*
14240266059SGregory Neil Shapiro ** SM_MBDB_LOOKUP -- look up a local mail recipient, given name
14340266059SGregory Neil Shapiro **
14440266059SGregory Neil Shapiro ** Parameters:
14540266059SGregory Neil Shapiro ** name -- name of local mail recipient
14640266059SGregory Neil Shapiro ** user -- pointer to structure to fill in on success
14740266059SGregory Neil Shapiro **
14840266059SGregory Neil Shapiro ** Results:
14940266059SGregory Neil Shapiro ** On success, fill in *user and return EX_OK.
15040266059SGregory Neil Shapiro ** If the user does not exist, return EX_NOUSER.
15140266059SGregory Neil Shapiro ** If a temporary failure (eg, a network failure) occurred,
15240266059SGregory Neil Shapiro ** return EX_TEMPFAIL. Otherwise return EX_OSERR.
15340266059SGregory Neil Shapiro */
15440266059SGregory Neil Shapiro
15540266059SGregory Neil Shapiro int
sm_mbdb_lookup(name,user)15640266059SGregory Neil Shapiro sm_mbdb_lookup(name, user)
15740266059SGregory Neil Shapiro char *name;
15840266059SGregory Neil Shapiro SM_MBDB_T *user;
15940266059SGregory Neil Shapiro {
16094c01205SGregory Neil Shapiro int ret = EX_NOUSER;
16194c01205SGregory Neil Shapiro
16294c01205SGregory Neil Shapiro if (SmMbdbType->mbdb_lookup != NULL)
16394c01205SGregory Neil Shapiro ret = SmMbdbType->mbdb_lookup(name, user);
16494c01205SGregory Neil Shapiro return ret;
16540266059SGregory Neil Shapiro }
16640266059SGregory Neil Shapiro
16740266059SGregory Neil Shapiro /*
16840266059SGregory Neil Shapiro ** SM_MBDB_FROMPW -- copy from struct pw to SM_MBDB_T
16940266059SGregory Neil Shapiro **
17040266059SGregory Neil Shapiro ** Parameters:
17140266059SGregory Neil Shapiro ** user -- destination user information structure
17240266059SGregory Neil Shapiro ** pw -- source passwd structure
17340266059SGregory Neil Shapiro **
17440266059SGregory Neil Shapiro ** Results:
17540266059SGregory Neil Shapiro ** none.
17640266059SGregory Neil Shapiro */
17740266059SGregory Neil Shapiro
17840266059SGregory Neil Shapiro void
sm_mbdb_frompw(user,pw)17940266059SGregory Neil Shapiro sm_mbdb_frompw(user, pw)
18040266059SGregory Neil Shapiro SM_MBDB_T *user;
18140266059SGregory Neil Shapiro struct passwd *pw;
18240266059SGregory Neil Shapiro {
18340266059SGregory Neil Shapiro SM_REQUIRE(user != NULL);
18440266059SGregory Neil Shapiro (void) sm_strlcpy(user->mbdb_name, pw->pw_name,
18540266059SGregory Neil Shapiro sizeof(user->mbdb_name));
18640266059SGregory Neil Shapiro user->mbdb_uid = pw->pw_uid;
18740266059SGregory Neil Shapiro user->mbdb_gid = pw->pw_gid;
18840266059SGregory Neil Shapiro sm_pwfullname(pw->pw_gecos, pw->pw_name, user->mbdb_fullname,
18940266059SGregory Neil Shapiro sizeof(user->mbdb_fullname));
19040266059SGregory Neil Shapiro (void) sm_strlcpy(user->mbdb_homedir, pw->pw_dir,
19140266059SGregory Neil Shapiro sizeof(user->mbdb_homedir));
19240266059SGregory Neil Shapiro (void) sm_strlcpy(user->mbdb_shell, pw->pw_shell,
19340266059SGregory Neil Shapiro sizeof(user->mbdb_shell));
19440266059SGregory Neil Shapiro }
19540266059SGregory Neil Shapiro
19640266059SGregory Neil Shapiro /*
19740266059SGregory Neil Shapiro ** SM_PWFULLNAME -- build full name of user from pw_gecos field.
19840266059SGregory Neil Shapiro **
19940266059SGregory Neil Shapiro ** This routine interprets the strange entry that would appear
20040266059SGregory Neil Shapiro ** in the GECOS field of the password file.
20140266059SGregory Neil Shapiro **
20240266059SGregory Neil Shapiro ** Parameters:
20340266059SGregory Neil Shapiro ** gecos -- name to build.
20440266059SGregory Neil Shapiro ** user -- the login name of this user (for &).
20540266059SGregory Neil Shapiro ** buf -- place to put the result.
20640266059SGregory Neil Shapiro ** buflen -- length of buf.
20740266059SGregory Neil Shapiro **
20840266059SGregory Neil Shapiro ** Returns:
20940266059SGregory Neil Shapiro ** none.
21040266059SGregory Neil Shapiro */
21140266059SGregory Neil Shapiro
212605302a5SGregory Neil Shapiro #if _FFR_HANDLE_ISO8859_GECOS
213605302a5SGregory Neil Shapiro static char Latin1ToASCII[128] =
214605302a5SGregory Neil Shapiro {
215605302a5SGregory Neil Shapiro 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
216605302a5SGregory Neil Shapiro 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33,
217605302a5SGregory Neil Shapiro 99, 80, 36, 89, 124, 36, 34, 99, 97, 60, 45, 45, 114, 45, 111, 42,
218605302a5SGregory Neil Shapiro 50, 51, 39, 117, 80, 46, 44, 49, 111, 62, 42, 42, 42, 63, 65, 65,
219605302a5SGregory Neil Shapiro 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73, 68, 78, 79,
220605302a5SGregory Neil Shapiro 79, 79, 79, 79, 88, 79, 85, 85, 85, 85, 89, 80, 66, 97, 97, 97, 97,
221605302a5SGregory Neil Shapiro 97, 97, 97, 99, 101, 101, 101, 101, 105, 105, 105, 105, 100, 110,
222605302a5SGregory Neil Shapiro 111, 111, 111, 111, 111, 47, 111, 117, 117, 117, 117, 121, 112, 121
223605302a5SGregory Neil Shapiro };
224605302a5SGregory Neil Shapiro #endif /* _FFR_HANDLE_ISO8859_GECOS */
225605302a5SGregory Neil Shapiro
22640266059SGregory Neil Shapiro void
sm_pwfullname(gecos,user,buf,buflen)22740266059SGregory Neil Shapiro sm_pwfullname(gecos, user, buf, buflen)
22840266059SGregory Neil Shapiro register char *gecos;
22940266059SGregory Neil Shapiro char *user;
23040266059SGregory Neil Shapiro char *buf;
23140266059SGregory Neil Shapiro size_t buflen;
23240266059SGregory Neil Shapiro {
23340266059SGregory Neil Shapiro register char *p;
23440266059SGregory Neil Shapiro register char *bp = buf;
23540266059SGregory Neil Shapiro
23640266059SGregory Neil Shapiro if (*gecos == '*')
23740266059SGregory Neil Shapiro gecos++;
23840266059SGregory Neil Shapiro
23940266059SGregory Neil Shapiro /* copy gecos, interpolating & to be full name */
24040266059SGregory Neil Shapiro for (p = gecos; *p != '\0' && *p != ',' && *p != ';' && *p != '%'; p++)
24140266059SGregory Neil Shapiro {
24240266059SGregory Neil Shapiro if (bp >= &buf[buflen - 1])
24340266059SGregory Neil Shapiro {
24440266059SGregory Neil Shapiro /* buffer overflow -- just use login name */
24540266059SGregory Neil Shapiro (void) sm_strlcpy(buf, user, buflen);
24640266059SGregory Neil Shapiro return;
24740266059SGregory Neil Shapiro }
24840266059SGregory Neil Shapiro if (*p == '&')
24940266059SGregory Neil Shapiro {
25040266059SGregory Neil Shapiro /* interpolate full name */
25140266059SGregory Neil Shapiro (void) sm_strlcpy(bp, user, buflen - (bp - buf));
25240266059SGregory Neil Shapiro *bp = toupper(*bp);
25340266059SGregory Neil Shapiro bp += strlen(bp);
25440266059SGregory Neil Shapiro }
25540266059SGregory Neil Shapiro else
256605302a5SGregory Neil Shapiro {
257605302a5SGregory Neil Shapiro #if _FFR_HANDLE_ISO8859_GECOS
258605302a5SGregory Neil Shapiro if ((unsigned char) *p >= 128)
259605302a5SGregory Neil Shapiro *bp++ = Latin1ToASCII[(unsigned char) *p - 128];
260605302a5SGregory Neil Shapiro else
2615b0945b5SGregory Neil Shapiro #endif
262*2fb4f839SGregory Neil Shapiro /* "else" in #if code above */
26340266059SGregory Neil Shapiro *bp++ = *p;
26440266059SGregory Neil Shapiro }
265605302a5SGregory Neil Shapiro }
26640266059SGregory Neil Shapiro *bp = '\0';
26740266059SGregory Neil Shapiro }
26840266059SGregory Neil Shapiro
26940266059SGregory Neil Shapiro /*
27040266059SGregory Neil Shapiro ** /etc/passwd implementation.
27140266059SGregory Neil Shapiro */
27240266059SGregory Neil Shapiro
27340266059SGregory Neil Shapiro /*
27440266059SGregory Neil Shapiro ** MBDB_PW_INITIALIZE -- initialize getpwnam() version
27540266059SGregory Neil Shapiro **
27640266059SGregory Neil Shapiro ** Parameters:
27740266059SGregory Neil Shapiro ** arg -- unused.
27840266059SGregory Neil Shapiro **
27940266059SGregory Neil Shapiro ** Results:
28040266059SGregory Neil Shapiro ** EX_OK.
28140266059SGregory Neil Shapiro */
28240266059SGregory Neil Shapiro
28340266059SGregory Neil Shapiro /* ARGSUSED0 */
28440266059SGregory Neil Shapiro static int
mbdb_pw_initialize(arg)28540266059SGregory Neil Shapiro mbdb_pw_initialize(arg)
28640266059SGregory Neil Shapiro char *arg;
28740266059SGregory Neil Shapiro {
28840266059SGregory Neil Shapiro return EX_OK;
28940266059SGregory Neil Shapiro }
29040266059SGregory Neil Shapiro
29140266059SGregory Neil Shapiro /*
29240266059SGregory Neil Shapiro ** MBDB_PW_LOOKUP -- look up a local mail recipient, given name
29340266059SGregory Neil Shapiro **
29440266059SGregory Neil Shapiro ** Parameters:
29540266059SGregory Neil Shapiro ** name -- name of local mail recipient
29640266059SGregory Neil Shapiro ** user -- pointer to structure to fill in on success
29740266059SGregory Neil Shapiro **
29840266059SGregory Neil Shapiro ** Results:
29940266059SGregory Neil Shapiro ** On success, fill in *user and return EX_OK.
30040266059SGregory Neil Shapiro ** Failure: EX_NOUSER.
30140266059SGregory Neil Shapiro */
30240266059SGregory Neil Shapiro
30340266059SGregory Neil Shapiro static int
mbdb_pw_lookup(name,user)30440266059SGregory Neil Shapiro mbdb_pw_lookup(name, user)
30540266059SGregory Neil Shapiro char *name;
30640266059SGregory Neil Shapiro SM_MBDB_T *user;
30740266059SGregory Neil Shapiro {
30840266059SGregory Neil Shapiro struct passwd *pw;
30940266059SGregory Neil Shapiro
310da7d7b9cSGregory Neil Shapiro #if HESIOD && !HESIOD_ALLOW_NUMERIC_LOGIN
31140266059SGregory Neil Shapiro /* DEC Hesiod getpwnam accepts numeric strings -- short circuit it */
31240266059SGregory Neil Shapiro {
31340266059SGregory Neil Shapiro char *p;
31440266059SGregory Neil Shapiro
31540266059SGregory Neil Shapiro for (p = name; *p != '\0'; p++)
31640266059SGregory Neil Shapiro if (!isascii(*p) || !isdigit(*p))
31740266059SGregory Neil Shapiro break;
31840266059SGregory Neil Shapiro if (*p == '\0')
31940266059SGregory Neil Shapiro return EX_NOUSER;
32040266059SGregory Neil Shapiro }
321da7d7b9cSGregory Neil Shapiro #endif /* HESIOD && !HESIOD_ALLOW_NUMERIC_LOGIN */
32240266059SGregory Neil Shapiro
32340266059SGregory Neil Shapiro errno = 0;
32440266059SGregory Neil Shapiro pw = getpwnam(name);
32540266059SGregory Neil Shapiro if (pw == NULL)
32640266059SGregory Neil Shapiro {
3275dd76dd0SGregory Neil Shapiro #if _FFR_USE_GETPWNAM_ERRNO
32840266059SGregory Neil Shapiro /*
3295dd76dd0SGregory Neil Shapiro ** Only enable this code iff
3305dd76dd0SGregory Neil Shapiro ** user unknown <-> getpwnam() == NULL && errno == 0
3315dd76dd0SGregory Neil Shapiro ** (i.e., errno unchanged); see the POSIX spec.
33240266059SGregory Neil Shapiro */
3335dd76dd0SGregory Neil Shapiro
3345dd76dd0SGregory Neil Shapiro if (errno != 0)
33540266059SGregory Neil Shapiro return EX_TEMPFAIL;
3365dd76dd0SGregory Neil Shapiro #endif /* _FFR_USE_GETPWNAM_ERRNO */
33740266059SGregory Neil Shapiro return EX_NOUSER;
33840266059SGregory Neil Shapiro }
33940266059SGregory Neil Shapiro
34040266059SGregory Neil Shapiro sm_mbdb_frompw(user, pw);
34140266059SGregory Neil Shapiro return EX_OK;
34240266059SGregory Neil Shapiro }
34340266059SGregory Neil Shapiro
34440266059SGregory Neil Shapiro /*
34540266059SGregory Neil Shapiro ** MBDB_PW_TERMINATE -- terminate connection to the mailbox database
34640266059SGregory Neil Shapiro **
34740266059SGregory Neil Shapiro ** Parameters:
34840266059SGregory Neil Shapiro ** none.
34940266059SGregory Neil Shapiro **
35040266059SGregory Neil Shapiro ** Results:
35140266059SGregory Neil Shapiro ** none.
35240266059SGregory Neil Shapiro */
35340266059SGregory Neil Shapiro
35440266059SGregory Neil Shapiro static void
mbdb_pw_terminate()35540266059SGregory Neil Shapiro mbdb_pw_terminate()
35640266059SGregory Neil Shapiro {
35740266059SGregory Neil Shapiro endpwent();
35840266059SGregory Neil Shapiro }
35940266059SGregory Neil Shapiro
360*2fb4f839SGregory Neil Shapiro #if LDAPMAP && _LDAP_EXAMPLE_
36140266059SGregory Neil Shapiro /*
36240266059SGregory Neil Shapiro ** LDAP example implementation based on RFC 2307, "An Approach for Using
36340266059SGregory Neil Shapiro ** LDAP as a Network Information Service":
36440266059SGregory Neil Shapiro **
36540266059SGregory Neil Shapiro ** ( nisSchema.1.0 NAME 'uidNumber'
36640266059SGregory Neil Shapiro ** DESC 'An integer uniquely identifying a user in an
36740266059SGregory Neil Shapiro ** administrative domain'
36840266059SGregory Neil Shapiro ** EQUALITY integerMatch SYNTAX 'INTEGER' SINGLE-VALUE )
36940266059SGregory Neil Shapiro **
37040266059SGregory Neil Shapiro ** ( nisSchema.1.1 NAME 'gidNumber'
37140266059SGregory Neil Shapiro ** DESC 'An integer uniquely identifying a group in an
37240266059SGregory Neil Shapiro ** administrative domain'
37340266059SGregory Neil Shapiro ** EQUALITY integerMatch SYNTAX 'INTEGER' SINGLE-VALUE )
37440266059SGregory Neil Shapiro **
37540266059SGregory Neil Shapiro ** ( nisSchema.1.2 NAME 'gecos'
37640266059SGregory Neil Shapiro ** DESC 'The GECOS field; the common name'
37740266059SGregory Neil Shapiro ** EQUALITY caseIgnoreIA5Match
37840266059SGregory Neil Shapiro ** SUBSTRINGS caseIgnoreIA5SubstringsMatch
37940266059SGregory Neil Shapiro ** SYNTAX 'IA5String' SINGLE-VALUE )
38040266059SGregory Neil Shapiro **
38140266059SGregory Neil Shapiro ** ( nisSchema.1.3 NAME 'homeDirectory'
38240266059SGregory Neil Shapiro ** DESC 'The absolute path to the home directory'
38340266059SGregory Neil Shapiro ** EQUALITY caseExactIA5Match
38440266059SGregory Neil Shapiro ** SYNTAX 'IA5String' SINGLE-VALUE )
38540266059SGregory Neil Shapiro **
38640266059SGregory Neil Shapiro ** ( nisSchema.1.4 NAME 'loginShell'
38740266059SGregory Neil Shapiro ** DESC 'The path to the login shell'
38840266059SGregory Neil Shapiro ** EQUALITY caseExactIA5Match
38940266059SGregory Neil Shapiro ** SYNTAX 'IA5String' SINGLE-VALUE )
39040266059SGregory Neil Shapiro **
39140266059SGregory Neil Shapiro ** ( nisSchema.2.0 NAME 'posixAccount' SUP top AUXILIARY
39240266059SGregory Neil Shapiro ** DESC 'Abstraction of an account with POSIX attributes'
39340266059SGregory Neil Shapiro ** MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
39440266059SGregory Neil Shapiro ** MAY ( userPassword $ loginShell $ gecos $ description ) )
39540266059SGregory Neil Shapiro **
39640266059SGregory Neil Shapiro */
39740266059SGregory Neil Shapiro
39840266059SGregory Neil Shapiro # define MBDB_LDAP_LABEL "MailboxDatabase"
39940266059SGregory Neil Shapiro
40040266059SGregory Neil Shapiro # ifndef MBDB_LDAP_FILTER
40140266059SGregory Neil Shapiro # define MBDB_LDAP_FILTER "(&(objectClass=posixAccount)(uid=%0))"
4025b0945b5SGregory Neil Shapiro # endif
40340266059SGregory Neil Shapiro
40440266059SGregory Neil Shapiro # ifndef MBDB_DEFAULT_LDAP_BASEDN
40540266059SGregory Neil Shapiro # define MBDB_DEFAULT_LDAP_BASEDN NULL
4065b0945b5SGregory Neil Shapiro # endif
40740266059SGregory Neil Shapiro
40840266059SGregory Neil Shapiro # ifndef MBDB_DEFAULT_LDAP_SERVER
40940266059SGregory Neil Shapiro # define MBDB_DEFAULT_LDAP_SERVER NULL
4105b0945b5SGregory Neil Shapiro # endif
41140266059SGregory Neil Shapiro
41240266059SGregory Neil Shapiro /*
41340266059SGregory Neil Shapiro ** MBDB_LDAP_INITIALIZE -- initialize LDAP version
41440266059SGregory Neil Shapiro **
41540266059SGregory Neil Shapiro ** Parameters:
41640266059SGregory Neil Shapiro ** arg -- LDAP specification
41740266059SGregory Neil Shapiro **
41840266059SGregory Neil Shapiro ** Results:
41940266059SGregory Neil Shapiro ** EX_OK on success, or an EX_* code on failure.
42040266059SGregory Neil Shapiro */
42140266059SGregory Neil Shapiro
42240266059SGregory Neil Shapiro static int
mbdb_ldap_initialize(arg)42340266059SGregory Neil Shapiro mbdb_ldap_initialize(arg)
42440266059SGregory Neil Shapiro char *arg;
42540266059SGregory Neil Shapiro {
42640266059SGregory Neil Shapiro sm_ldap_clear(&LDAPLMAP);
42740266059SGregory Neil Shapiro LDAPLMAP.ldap_base = MBDB_DEFAULT_LDAP_BASEDN;
428e92d3f3fSGregory Neil Shapiro LDAPLMAP.ldap_host = MBDB_DEFAULT_LDAP_SERVER;
42940266059SGregory Neil Shapiro LDAPLMAP.ldap_filter = MBDB_LDAP_FILTER;
43040266059SGregory Neil Shapiro
43140266059SGregory Neil Shapiro /* Only want one match */
43240266059SGregory Neil Shapiro LDAPLMAP.ldap_sizelimit = 1;
43340266059SGregory Neil Shapiro
434e92d3f3fSGregory Neil Shapiro /* interpolate new ldap_base and ldap_host from arg if given */
43540266059SGregory Neil Shapiro if (arg != NULL && *arg != '\0')
43640266059SGregory Neil Shapiro {
43740266059SGregory Neil Shapiro char *new;
43840266059SGregory Neil Shapiro char *sep;
43940266059SGregory Neil Shapiro size_t len;
44040266059SGregory Neil Shapiro
44140266059SGregory Neil Shapiro len = strlen(arg) + 1;
44240266059SGregory Neil Shapiro new = sm_malloc(len);
44340266059SGregory Neil Shapiro if (new == NULL)
44440266059SGregory Neil Shapiro return EX_TEMPFAIL;
44540266059SGregory Neil Shapiro (void) sm_strlcpy(new, arg, len);
44640266059SGregory Neil Shapiro sep = strrchr(new, '@');
44740266059SGregory Neil Shapiro if (sep != NULL)
44840266059SGregory Neil Shapiro {
44940266059SGregory Neil Shapiro *sep++ = '\0';
450e92d3f3fSGregory Neil Shapiro LDAPLMAP.ldap_host = sep;
45140266059SGregory Neil Shapiro }
45240266059SGregory Neil Shapiro LDAPLMAP.ldap_base = new;
45340266059SGregory Neil Shapiro }
45440266059SGregory Neil Shapiro return EX_OK;
45540266059SGregory Neil Shapiro }
45640266059SGregory Neil Shapiro
45740266059SGregory Neil Shapiro
45840266059SGregory Neil Shapiro /*
45940266059SGregory Neil Shapiro ** MBDB_LDAP_LOOKUP -- look up a local mail recipient, given name
46040266059SGregory Neil Shapiro **
46140266059SGregory Neil Shapiro ** Parameters:
46240266059SGregory Neil Shapiro ** name -- name of local mail recipient
46340266059SGregory Neil Shapiro ** user -- pointer to structure to fill in on success
46440266059SGregory Neil Shapiro **
46540266059SGregory Neil Shapiro ** Results:
46640266059SGregory Neil Shapiro ** On success, fill in *user and return EX_OK.
46740266059SGregory Neil Shapiro ** Failure: EX_NOUSER.
46840266059SGregory Neil Shapiro */
46940266059SGregory Neil Shapiro
47040266059SGregory Neil Shapiro #define NEED_FULLNAME 0x01
47140266059SGregory Neil Shapiro #define NEED_HOMEDIR 0x02
47240266059SGregory Neil Shapiro #define NEED_SHELL 0x04
47340266059SGregory Neil Shapiro #define NEED_UID 0x08
47440266059SGregory Neil Shapiro #define NEED_GID 0x10
47540266059SGregory Neil Shapiro
47640266059SGregory Neil Shapiro static int
mbdb_ldap_lookup(name,user)47740266059SGregory Neil Shapiro mbdb_ldap_lookup(name, user)
47840266059SGregory Neil Shapiro char *name;
47940266059SGregory Neil Shapiro SM_MBDB_T *user;
48040266059SGregory Neil Shapiro {
48140266059SGregory Neil Shapiro int msgid;
48240266059SGregory Neil Shapiro int need;
48340266059SGregory Neil Shapiro int ret;
48440266059SGregory Neil Shapiro int save_errno;
48540266059SGregory Neil Shapiro LDAPMessage *entry;
48640266059SGregory Neil Shapiro BerElement *ber;
48740266059SGregory Neil Shapiro char *attr = NULL;
48840266059SGregory Neil Shapiro
48940266059SGregory Neil Shapiro if (strlen(name) >= sizeof(user->mbdb_name))
49040266059SGregory Neil Shapiro {
49140266059SGregory Neil Shapiro errno = EINVAL;
49240266059SGregory Neil Shapiro return EX_NOUSER;
49340266059SGregory Neil Shapiro }
49440266059SGregory Neil Shapiro
49540266059SGregory Neil Shapiro if (LDAPLMAP.ldap_filter == NULL)
49640266059SGregory Neil Shapiro {
49740266059SGregory Neil Shapiro /* map not initialized, but don't have arg here */
49840266059SGregory Neil Shapiro errno = EFAULT;
49940266059SGregory Neil Shapiro return EX_TEMPFAIL;
50040266059SGregory Neil Shapiro }
50140266059SGregory Neil Shapiro
50213bd1963SGregory Neil Shapiro if (LDAPLMAP.ldap_pid != getpid())
50313bd1963SGregory Neil Shapiro {
50413bd1963SGregory Neil Shapiro /* re-open map in this child process */
50513bd1963SGregory Neil Shapiro LDAPLMAP.ldap_ld = NULL;
50613bd1963SGregory Neil Shapiro }
50713bd1963SGregory Neil Shapiro
50840266059SGregory Neil Shapiro if (LDAPLMAP.ldap_ld == NULL)
50940266059SGregory Neil Shapiro {
51040266059SGregory Neil Shapiro /* map not open, try to open now */
51140266059SGregory Neil Shapiro if (!sm_ldap_start(MBDB_LDAP_LABEL, &LDAPLMAP))
51240266059SGregory Neil Shapiro return EX_TEMPFAIL;
51340266059SGregory Neil Shapiro }
51440266059SGregory Neil Shapiro
51540266059SGregory Neil Shapiro sm_ldap_setopts(LDAPLMAP.ldap_ld, &LDAPLMAP);
51640266059SGregory Neil Shapiro msgid = sm_ldap_search(&LDAPLMAP, name);
51740266059SGregory Neil Shapiro if (msgid == -1)
51840266059SGregory Neil Shapiro {
51940266059SGregory Neil Shapiro save_errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld) + E_LDAPBASE;
52040266059SGregory Neil Shapiro # ifdef LDAP_SERVER_DOWN
52140266059SGregory Neil Shapiro if (errno == LDAP_SERVER_DOWN)
52240266059SGregory Neil Shapiro {
52340266059SGregory Neil Shapiro /* server disappeared, try reopen on next search */
52440266059SGregory Neil Shapiro sm_ldap_close(&LDAPLMAP);
52540266059SGregory Neil Shapiro }
52640266059SGregory Neil Shapiro # endif /* LDAP_SERVER_DOWN */
52740266059SGregory Neil Shapiro errno = save_errno;
52840266059SGregory Neil Shapiro return EX_TEMPFAIL;
52940266059SGregory Neil Shapiro }
53040266059SGregory Neil Shapiro
53140266059SGregory Neil Shapiro /* Get results */
53240266059SGregory Neil Shapiro ret = ldap_result(LDAPLMAP.ldap_ld, msgid, 1,
53340266059SGregory Neil Shapiro (LDAPLMAP.ldap_timeout.tv_sec == 0 ? NULL :
53440266059SGregory Neil Shapiro &(LDAPLMAP.ldap_timeout)),
53540266059SGregory Neil Shapiro &(LDAPLMAP.ldap_res));
53640266059SGregory Neil Shapiro
53740266059SGregory Neil Shapiro if (ret != LDAP_RES_SEARCH_RESULT &&
53840266059SGregory Neil Shapiro ret != LDAP_RES_SEARCH_ENTRY)
53940266059SGregory Neil Shapiro {
54040266059SGregory Neil Shapiro if (ret == 0)
54140266059SGregory Neil Shapiro errno = ETIMEDOUT;
54240266059SGregory Neil Shapiro else
54340266059SGregory Neil Shapiro errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld);
54440266059SGregory Neil Shapiro ret = EX_TEMPFAIL;
54540266059SGregory Neil Shapiro goto abort;
54640266059SGregory Neil Shapiro }
54740266059SGregory Neil Shapiro
54840266059SGregory Neil Shapiro entry = ldap_first_entry(LDAPLMAP.ldap_ld, LDAPLMAP.ldap_res);
54940266059SGregory Neil Shapiro if (entry == NULL)
55040266059SGregory Neil Shapiro {
5519bd497b8SGregory Neil Shapiro int rc;
5529bd497b8SGregory Neil Shapiro
5539bd497b8SGregory Neil Shapiro /*
5549bd497b8SGregory Neil Shapiro ** We may have gotten an LDAP_RES_SEARCH_RESULT response
5559bd497b8SGregory Neil Shapiro ** with an error inside it, so we have to extract that
5569bd497b8SGregory Neil Shapiro ** with ldap_parse_result(). This can happen when talking
5579bd497b8SGregory Neil Shapiro ** to an LDAP proxy whose backend has gone down.
5589bd497b8SGregory Neil Shapiro */
5599bd497b8SGregory Neil Shapiro
5609bd497b8SGregory Neil Shapiro save_errno = ldap_parse_result(LDAPLMAP.ldap_ld,
5619bd497b8SGregory Neil Shapiro LDAPLMAP.ldap_res, &rc, NULL,
5629bd497b8SGregory Neil Shapiro NULL, NULL, NULL, 0);
5639bd497b8SGregory Neil Shapiro if (save_errno == LDAP_SUCCESS)
5649bd497b8SGregory Neil Shapiro save_errno = rc;
56540266059SGregory Neil Shapiro if (save_errno == LDAP_SUCCESS)
56640266059SGregory Neil Shapiro {
56740266059SGregory Neil Shapiro errno = ENOENT;
56840266059SGregory Neil Shapiro ret = EX_NOUSER;
56940266059SGregory Neil Shapiro }
57040266059SGregory Neil Shapiro else
57140266059SGregory Neil Shapiro {
57240266059SGregory Neil Shapiro errno = save_errno;
57340266059SGregory Neil Shapiro ret = EX_TEMPFAIL;
57440266059SGregory Neil Shapiro }
57540266059SGregory Neil Shapiro goto abort;
57640266059SGregory Neil Shapiro }
57740266059SGregory Neil Shapiro
57840266059SGregory Neil Shapiro # if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
57940266059SGregory Neil Shapiro /*
58040266059SGregory Neil Shapiro ** Reset value to prevent lingering
58140266059SGregory Neil Shapiro ** LDAP_DECODING_ERROR due to
58240266059SGregory Neil Shapiro ** OpenLDAP 1.X's hack (see below)
58340266059SGregory Neil Shapiro */
58440266059SGregory Neil Shapiro
58540266059SGregory Neil Shapiro LDAPLMAP.ldap_ld->ld_errno = LDAP_SUCCESS;
58640266059SGregory Neil Shapiro # endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
58740266059SGregory Neil Shapiro
58840266059SGregory Neil Shapiro ret = EX_OK;
58940266059SGregory Neil Shapiro need = NEED_FULLNAME|NEED_HOMEDIR|NEED_SHELL|NEED_UID|NEED_GID;
59040266059SGregory Neil Shapiro for (attr = ldap_first_attribute(LDAPLMAP.ldap_ld, entry, &ber);
59140266059SGregory Neil Shapiro attr != NULL;
59240266059SGregory Neil Shapiro attr = ldap_next_attribute(LDAPLMAP.ldap_ld, entry, ber))
59340266059SGregory Neil Shapiro {
59440266059SGregory Neil Shapiro char **vals;
59540266059SGregory Neil Shapiro
59640266059SGregory Neil Shapiro vals = ldap_get_values(LDAPLMAP.ldap_ld, entry, attr);
59740266059SGregory Neil Shapiro if (vals == NULL)
59840266059SGregory Neil Shapiro {
59940266059SGregory Neil Shapiro errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld);
60040266059SGregory Neil Shapiro if (errno == LDAP_SUCCESS)
60140266059SGregory Neil Shapiro {
60240266059SGregory Neil Shapiro ldap_memfree(attr);
60340266059SGregory Neil Shapiro continue;
60440266059SGregory Neil Shapiro }
60540266059SGregory Neil Shapiro
60640266059SGregory Neil Shapiro /* Must be an error */
60740266059SGregory Neil Shapiro errno += E_LDAPBASE;
60840266059SGregory Neil Shapiro ret = EX_TEMPFAIL;
60940266059SGregory Neil Shapiro goto abort;
61040266059SGregory Neil Shapiro }
61140266059SGregory Neil Shapiro
61240266059SGregory Neil Shapiro # if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT)
61340266059SGregory Neil Shapiro /*
61440266059SGregory Neil Shapiro ** Reset value to prevent lingering
61540266059SGregory Neil Shapiro ** LDAP_DECODING_ERROR due to
61640266059SGregory Neil Shapiro ** OpenLDAP 1.X's hack (see below)
61740266059SGregory Neil Shapiro */
61840266059SGregory Neil Shapiro
61940266059SGregory Neil Shapiro LDAPLMAP.ldap_ld->ld_errno = LDAP_SUCCESS;
62040266059SGregory Neil Shapiro # endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */
62140266059SGregory Neil Shapiro
62240266059SGregory Neil Shapiro if (vals[0] == NULL || vals[0][0] == '\0')
62340266059SGregory Neil Shapiro goto skip;
62440266059SGregory Neil Shapiro
62540266059SGregory Neil Shapiro if (strcasecmp(attr, "gecos") == 0)
62640266059SGregory Neil Shapiro {
62740266059SGregory Neil Shapiro if (!bitset(NEED_FULLNAME, need) ||
62840266059SGregory Neil Shapiro strlen(vals[0]) >= sizeof(user->mbdb_fullname))
62940266059SGregory Neil Shapiro goto skip;
63040266059SGregory Neil Shapiro
63140266059SGregory Neil Shapiro sm_pwfullname(vals[0], name, user->mbdb_fullname,
63240266059SGregory Neil Shapiro sizeof(user->mbdb_fullname));
63340266059SGregory Neil Shapiro need &= ~NEED_FULLNAME;
63440266059SGregory Neil Shapiro }
63540266059SGregory Neil Shapiro else if (strcasecmp(attr, "homeDirectory") == 0)
63640266059SGregory Neil Shapiro {
63740266059SGregory Neil Shapiro if (!bitset(NEED_HOMEDIR, need) ||
63840266059SGregory Neil Shapiro strlen(vals[0]) >= sizeof(user->mbdb_homedir))
63940266059SGregory Neil Shapiro goto skip;
64040266059SGregory Neil Shapiro
64140266059SGregory Neil Shapiro (void) sm_strlcpy(user->mbdb_homedir, vals[0],
64240266059SGregory Neil Shapiro sizeof(user->mbdb_homedir));
64340266059SGregory Neil Shapiro need &= ~NEED_HOMEDIR;
64440266059SGregory Neil Shapiro }
64540266059SGregory Neil Shapiro else if (strcasecmp(attr, "loginShell") == 0)
64640266059SGregory Neil Shapiro {
64740266059SGregory Neil Shapiro if (!bitset(NEED_SHELL, need) ||
64840266059SGregory Neil Shapiro strlen(vals[0]) >= sizeof(user->mbdb_shell))
64940266059SGregory Neil Shapiro goto skip;
65040266059SGregory Neil Shapiro
65140266059SGregory Neil Shapiro (void) sm_strlcpy(user->mbdb_shell, vals[0],
65240266059SGregory Neil Shapiro sizeof(user->mbdb_shell));
65340266059SGregory Neil Shapiro need &= ~NEED_SHELL;
65440266059SGregory Neil Shapiro }
65540266059SGregory Neil Shapiro else if (strcasecmp(attr, "uidNumber") == 0)
65640266059SGregory Neil Shapiro {
65740266059SGregory Neil Shapiro char *p;
65840266059SGregory Neil Shapiro
65940266059SGregory Neil Shapiro if (!bitset(NEED_UID, need))
66040266059SGregory Neil Shapiro goto skip;
66140266059SGregory Neil Shapiro
66240266059SGregory Neil Shapiro for (p = vals[0]; *p != '\0'; p++)
66340266059SGregory Neil Shapiro {
66440266059SGregory Neil Shapiro /* allow negative numbers */
66540266059SGregory Neil Shapiro if (p == vals[0] && *p == '-')
66640266059SGregory Neil Shapiro {
66740266059SGregory Neil Shapiro /* but not simply '-' */
66840266059SGregory Neil Shapiro if (*(p + 1) == '\0')
66940266059SGregory Neil Shapiro goto skip;
67040266059SGregory Neil Shapiro }
67140266059SGregory Neil Shapiro else if (!isascii(*p) || !isdigit(*p))
67240266059SGregory Neil Shapiro goto skip;
67340266059SGregory Neil Shapiro }
67440266059SGregory Neil Shapiro user->mbdb_uid = atoi(vals[0]);
67540266059SGregory Neil Shapiro need &= ~NEED_UID;
67640266059SGregory Neil Shapiro }
67740266059SGregory Neil Shapiro else if (strcasecmp(attr, "gidNumber") == 0)
67840266059SGregory Neil Shapiro {
67940266059SGregory Neil Shapiro char *p;
68040266059SGregory Neil Shapiro
68140266059SGregory Neil Shapiro if (!bitset(NEED_GID, need))
68240266059SGregory Neil Shapiro goto skip;
68340266059SGregory Neil Shapiro
68440266059SGregory Neil Shapiro for (p = vals[0]; *p != '\0'; p++)
68540266059SGregory Neil Shapiro {
68640266059SGregory Neil Shapiro /* allow negative numbers */
68740266059SGregory Neil Shapiro if (p == vals[0] && *p == '-')
68840266059SGregory Neil Shapiro {
68940266059SGregory Neil Shapiro /* but not simply '-' */
69040266059SGregory Neil Shapiro if (*(p + 1) == '\0')
69140266059SGregory Neil Shapiro goto skip;
69240266059SGregory Neil Shapiro }
69340266059SGregory Neil Shapiro else if (!isascii(*p) || !isdigit(*p))
69440266059SGregory Neil Shapiro goto skip;
69540266059SGregory Neil Shapiro }
69640266059SGregory Neil Shapiro user->mbdb_gid = atoi(vals[0]);
69740266059SGregory Neil Shapiro need &= ~NEED_GID;
69840266059SGregory Neil Shapiro }
69940266059SGregory Neil Shapiro
70040266059SGregory Neil Shapiro skip:
70140266059SGregory Neil Shapiro ldap_value_free(vals);
70240266059SGregory Neil Shapiro ldap_memfree(attr);
70340266059SGregory Neil Shapiro }
70440266059SGregory Neil Shapiro
70540266059SGregory Neil Shapiro errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld);
70640266059SGregory Neil Shapiro
70740266059SGregory Neil Shapiro /*
70840266059SGregory Neil Shapiro ** We check errno != LDAP_DECODING_ERROR since
70940266059SGregory Neil Shapiro ** OpenLDAP 1.X has a very ugly *undocumented*
71040266059SGregory Neil Shapiro ** hack of returning this error code from
71140266059SGregory Neil Shapiro ** ldap_next_attribute() if the library freed the
71240266059SGregory Neil Shapiro ** ber attribute. See:
71340266059SGregory Neil Shapiro ** http://www.openldap.org/lists/openldap-devel/9901/msg00064.html
71440266059SGregory Neil Shapiro */
71540266059SGregory Neil Shapiro
71640266059SGregory Neil Shapiro if (errno != LDAP_SUCCESS &&
71740266059SGregory Neil Shapiro errno != LDAP_DECODING_ERROR)
71840266059SGregory Neil Shapiro {
71940266059SGregory Neil Shapiro /* Must be an error */
72040266059SGregory Neil Shapiro errno += E_LDAPBASE;
72140266059SGregory Neil Shapiro ret = EX_TEMPFAIL;
72240266059SGregory Neil Shapiro goto abort;
72340266059SGregory Neil Shapiro }
72440266059SGregory Neil Shapiro
72540266059SGregory Neil Shapiro abort:
72640266059SGregory Neil Shapiro save_errno = errno;
72740266059SGregory Neil Shapiro if (attr != NULL)
72840266059SGregory Neil Shapiro {
72940266059SGregory Neil Shapiro ldap_memfree(attr);
73040266059SGregory Neil Shapiro attr = NULL;
73140266059SGregory Neil Shapiro }
73240266059SGregory Neil Shapiro if (LDAPLMAP.ldap_res != NULL)
73340266059SGregory Neil Shapiro {
73440266059SGregory Neil Shapiro ldap_msgfree(LDAPLMAP.ldap_res);
73540266059SGregory Neil Shapiro LDAPLMAP.ldap_res = NULL;
73640266059SGregory Neil Shapiro }
73740266059SGregory Neil Shapiro if (ret == EX_OK)
73840266059SGregory Neil Shapiro {
73940266059SGregory Neil Shapiro if (need == 0)
74040266059SGregory Neil Shapiro {
74140266059SGregory Neil Shapiro (void) sm_strlcpy(user->mbdb_name, name,
74240266059SGregory Neil Shapiro sizeof(user->mbdb_name));
74340266059SGregory Neil Shapiro save_errno = 0;
74440266059SGregory Neil Shapiro }
74540266059SGregory Neil Shapiro else
74640266059SGregory Neil Shapiro {
74740266059SGregory Neil Shapiro ret = EX_NOUSER;
74840266059SGregory Neil Shapiro save_errno = EINVAL;
74940266059SGregory Neil Shapiro }
75040266059SGregory Neil Shapiro }
75140266059SGregory Neil Shapiro errno = save_errno;
75240266059SGregory Neil Shapiro return ret;
75340266059SGregory Neil Shapiro }
75440266059SGregory Neil Shapiro
75540266059SGregory Neil Shapiro /*
75640266059SGregory Neil Shapiro ** MBDB_LDAP_TERMINATE -- terminate connection to the mailbox database
75740266059SGregory Neil Shapiro **
75840266059SGregory Neil Shapiro ** Parameters:
75940266059SGregory Neil Shapiro ** none.
76040266059SGregory Neil Shapiro **
76140266059SGregory Neil Shapiro ** Results:
76240266059SGregory Neil Shapiro ** none.
76340266059SGregory Neil Shapiro */
76440266059SGregory Neil Shapiro
76540266059SGregory Neil Shapiro static void
mbdb_ldap_terminate()76640266059SGregory Neil Shapiro mbdb_ldap_terminate()
76740266059SGregory Neil Shapiro {
76840266059SGregory Neil Shapiro sm_ldap_close(&LDAPLMAP);
76940266059SGregory Neil Shapiro }
770*2fb4f839SGregory Neil Shapiro #endif /* LDAPMAP && _LDAP_EXAMPLE_ */
771