]> git.sur5r.net Git - openldap/blob - libraries/liblutil/getpeereid.c
Fix previous commit, fstat arg was wrong.
[openldap] / libraries / liblutil / getpeereid.c
1 /* getpeereid.c */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #ifndef HAVE_GETPEEREID
11
12 #include <sys/types.h>
13 #include <ac/unistd.h>
14
15 #include <ac/socket.h>
16
17 #if HAVE_SYS_UCRED_H
18 #include <sys/ucred.h>
19 #endif
20
21 #if !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && defined(HAVE_SENDMSG)
22 #define DO_SENDMSG
23 #include <sys/stat.h>
24 #endif
25
26 int getpeereid( int s, uid_t *euid, gid_t *egid )
27 {
28 #ifdef LDAP_PF_LOCAL
29 #if defined( SO_PEERCRED )
30         struct ucred peercred;
31         size_t peercredlen = sizeof peercred;
32
33         if(( getsockopt( s, SOL_SOCKET, SO_PEERCRED,
34                 (void *)&peercred, &peercredlen ) == 0 )
35                 && ( peercredlen == sizeof peercred ))
36         {
37                 *euid = peercred.uid;
38                 *egid = peercred.gid;
39                 return 0;
40         }
41
42 #elif defined( LOCAL_PEERCRED )
43         struct xucred peercred;
44         socklen_t peercredlen = sizeof peercred;
45
46         if(( getsockopt( s, LOCAL_PEERCRED, 1,
47                 (void *)&peercred, &peercredlen ) == 0 )
48                 && ( peercred.cr_version == XUCRED_VERSION ))
49         {
50                 *euid = peercred.cr_uid;
51                 *egid = peercred.cr_gid;
52                 return 0;
53         }
54 #elif defined( DO_SENDMSG )
55         int dummy, fd[2];
56         struct iovec iov = {(char *)&dummy, sizeof(dummy)};
57         struct msghdr msg = {0};
58         struct stat st;
59         msg.msg_iov = &iov;
60         msg.msg_iovlen = 1;
61         msg.msg_accrights = (char *)fd;
62         msg.msg_accrightslen = sizeof(fd);
63         if( recvmsg( s, &msg, 0) >= 0 && msg.msg_accrightslen == sizeof(int) )
64         {
65                 /* We must receive a valid descriptor, it must be a pipe,
66                  * and it must only be accessible by its owner.
67                  */
68                 dummy = fstat( fd[0], &st );
69                 close(fd[0]);
70                 if( dummy == 0 && S_ISFIFO(st.st_mode) &&
71                         ((st.st_mode & (S_IRWXG|S_IRWXO)) == 0))
72                 {
73                         *euid = st.st_uid;
74                         *egid = st.st_gid;
75                         return 0;
76                 }
77         }
78 #endif
79 #endif
80
81         return -1;
82 }
83
84 #endif