1 /*
2  * COPYRIGHT (c) International Business Machines Corp. 2001-2017
3  *
4  * This program is provided under the terms of the Common Public License,
5  * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6  * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7  * found in the file LICENSE file or at
8  * https://opensource.org/licenses/cpl1.0.php
9  */
10 
11 #include <unistd.h>
12 #include <errno.h>
13 #include <stdarg.h>
14 #include <sys/types.h>
15 #include <sys/file.h>
16 #include <sys/stat.h>
17 #include <grp.h>
18 #include <string.h>
19 #include <fcntl.h>
20 
21 #include "log.h"
22 #include "slotmgr.h"
23 
24 #ifdef __sun
25 #define	LOCK_EX F_LOCK
26 #define	LOCK_UN F_ULOCK
27 #define	flock(fd, func) lockf(fd, func, 0)
28 #endif
29 #ifndef	LOCK_SH
30 #define	LOCK_SH 1       /* shared lock */
31 #endif
32 #ifndef	LOCK_EX
33 #define	LOCK_EX 2       /* exclusive lock */
34 #endif
35 #ifndef	LOCK_NB
36 #define	LOCK_NB 4       /* don't block when locking */
37 #endif
38 #ifndef	LOCK_UN
39 #define	LOCK_UN 8       /* unlock */
40 #endif
41 
42 static int xplfd = -1;
43 
CreateXProcLock(void)44 int CreateXProcLock(void)
45 {
46     struct group *grp;
47     mode_t mode = (S_IRUSR | S_IRGRP);
48     struct stat statbuf;
49 
50     if (xplfd == -1) {
51         if (stat(OCK_API_LOCK_FILE, &statbuf) == 0) {
52             xplfd = open(OCK_API_LOCK_FILE, O_RDONLY, mode);
53         } else {
54             xplfd = open(OCK_API_LOCK_FILE, O_CREAT | O_RDONLY, mode);
55 
56             if (xplfd != -1) {
57                 if (fchmod(xplfd, mode) == -1) {
58                     DbgLog(DL0, "%s:fchmod(%s):%s\n",
59                            __func__, OCK_API_LOCK_FILE, strerror(errno));
60                     goto error;
61                 }
62 
63                 grp = getgrnam(PKCS11GROUP);
64                 if (grp != NULL) {
65                     if (fchown(xplfd, -1, grp->gr_gid) == -1) {
66                         DbgLog(DL0, "%s:fchown(%s):%s\n",
67                                __func__,
68                                OCK_API_LOCK_FILE, strerror(errno));
69                         goto error;
70                     }
71                 } else {
72                     DbgLog(DL0, "%s:getgrnam():%s\n",
73                            __func__, strerror(errno));
74                     goto error;
75                 }
76             }
77         }
78         if (xplfd == -1) {
79             DbgLog(DL0, "open(%s): %s\n", OCK_API_LOCK_FILE, strerror(errno));
80             return FALSE;
81         }
82     }
83 
84     return TRUE;
85 
86 error:
87     if (xplfd != -1)
88         close(xplfd);
89 
90     return FALSE;
91 }
92 
XProcLock(void)93 int XProcLock(void)
94 {
95     if (xplfd != -1)
96         flock(xplfd, LOCK_EX);
97 
98     return TRUE;
99 }
100 
XProcUnLock(void)101 int XProcUnLock(void)
102 {
103     if (xplfd != -1)
104         flock(xplfd, LOCK_UN);
105 
106     return TRUE;
107 }
108 
109 /******************************************************************************
110  *
111  * InitializeMutexes -
112  *
113  *   Initializes the global shared memory mutex, and sets up mtxattr,
114  *   the attribute identifier used to create all the per-process mutexes
115  *
116  ******************************************************************************/
117 
InitializeMutexes(void)118 int InitializeMutexes(void)
119 {
120     int err;
121 
122     if ((err = CreateXProcLock()) != TRUE) {
123         DbgLog(DL0,
124                "InitializeMutexes: CreateXProcLock() failed - returned %#x\n",
125                err);
126         return FALSE;
127     }
128 
129     return TRUE;
130 }
131 
132 /***********************************************************************
133  *   DestroyMutexes -
134  *
135  *   Destroys all the mutexes used by the program
136  *
137  ***********************************************************************/
138 
DestroyMutexes(void)139 int DestroyMutexes(void)
140 {
141     /* Get the global shared memory mutex */
142     if (XProcLock() != CKR_OK)
143         return FALSE;
144 
145     /* Give up the global shared memory mutex */
146 
147     if (XProcUnLock() != CKR_OK)
148         return FALSE;
149 
150     return TRUE;
151 }
152