1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <string.h>
4+ #include <errno.h>
5+ #include <unistd.h>
6+ #include <sys/types.h>
7+ #include <sys/socket.h>
8+ #include <sys/un.h>
9+ #include "zdtmtst.h"
10+
11+ const char * test_doc = "Test SCM_CREDENTIALS checkpoint/restore in unix socket queue\n" ;
12+ const char * test_author = "Ahmed Elaidy <elaidya225@gmail.com>" ;
13+ char * dirname ;
14+ TEST_OPTION (dirname , string , "directory name" , 1 );
15+ int main (int argc , char * argv [])
16+ {
17+ int sk [2 ];
18+ struct msghdr msg = {};
19+ struct iovec iov ;
20+ char buf [64 ];
21+ char cmsg_buf [CMSG_SPACE (sizeof (struct ucred ))];
22+ struct cmsghdr * cmsg ;
23+ struct ucred * cred ;
24+ struct ucred send_cred ;
25+ int opt = 1 ;
26+
27+ test_init (argc , argv );
28+
29+ if (socketpair (AF_UNIX , SOCK_DGRAM , 0 , sk ) < 0 )
30+ return pr_perror ("socketpair" );
31+
32+ if (setsockopt (sk [1 ], SOL_SOCKET , SO_PASSCRED , & opt , sizeof (opt )) < 0 )
33+ return pr_perror ("setsockopt SO_PASSCRED" );
34+
35+ /* Send a message with SCM_CREDENTIALS */
36+ send_cred .pid = getpid ();
37+ send_cred .uid = getuid ();
38+ send_cred .gid = getgid ();
39+
40+ iov .iov_base = buf ;
41+ iov .iov_len = sizeof (buf );
42+
43+ memset (cmsg_buf , 0 , sizeof (cmsg_buf ));
44+ msg .msg_iov = & iov ;
45+ msg .msg_iovlen = 1 ;
46+ msg .msg_control = cmsg_buf ;
47+ msg .msg_controllen = sizeof (cmsg_buf );
48+
49+ cmsg = CMSG_FIRSTHDR (& msg );
50+ cmsg -> cmsg_level = SOL_SOCKET ;
51+ cmsg -> cmsg_type = SCM_CREDENTIALS ;
52+ cmsg -> cmsg_len = CMSG_LEN (sizeof (struct ucred ));
53+ memcpy (CMSG_DATA (cmsg ), & send_cred , sizeof (struct ucred ));
54+
55+ strcpy (buf , "hello" );
56+ if (sendmsg (sk [0 ], & msg , 0 ) < 0 )
57+ return pr_perror ("sendmsg" );
58+
59+ test_daemon ();
60+ test_waitsig ();
61+
62+ /* Receive and verify credentials after restore */
63+ memset (buf , 0 , sizeof (buf ));
64+ memset (cmsg_buf , 0 , sizeof (cmsg_buf ));
65+ msg .msg_control = cmsg_buf ;
66+ msg .msg_controllen = sizeof (cmsg_buf );
67+ iov .iov_base = buf ;
68+ iov .iov_len = sizeof (buf );
69+
70+ if (recvmsg (sk [1 ], & msg , 0 ) < 0 )
71+ return pr_perror ("recvmsg" );
72+
73+ cmsg = CMSG_FIRSTHDR (& msg );
74+ if (!cmsg ) {
75+ fail ("no cmsg after restore" );
76+ return 1 ;
77+ }
78+
79+ if (cmsg -> cmsg_type != SCM_CREDENTIALS ) {
80+ fail ("wrong cmsg type after restore" );
81+ return 1 ;
82+ }
83+
84+ cred = (struct ucred * )CMSG_DATA (cmsg );
85+
86+ if (cred -> uid != send_cred .uid || cred -> gid != send_cred .gid ) {
87+ fail ("credentials mismatch after restore: "
88+ "uid %d/%d gid %d/%d" ,
89+ cred -> uid , send_cred .uid ,
90+ cred -> gid , send_cred .gid );
91+ return 1 ;
92+ }
93+
94+ close (sk [0 ]);
95+ close (sk [1 ]);
96+
97+ pass ();
98+ return 0 ;
99+ }
0 commit comments