/src/sudo/lib/util/locking.c
Line | Count | Source |
1 | | /* |
2 | | * SPDX-License-Identifier: ISC |
3 | | * |
4 | | * Copyright (c) 1999-2005, 2007, 2009-2015 |
5 | | * Todd C. Miller <Todd.Miller@sudo.ws> |
6 | | * |
7 | | * Permission to use, copy, modify, and distribute this software for any |
8 | | * purpose with or without fee is hereby granted, provided that the above |
9 | | * copyright notice and this permission notice appear in all copies. |
10 | | * |
11 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | | * |
19 | | * Sponsored in part by the Defense Advanced Research Projects |
20 | | * Agency (DARPA) and Air Force Research Laboratory, Air Force |
21 | | * Materiel Command, USAF, under agreement number F39502-99-1-0512. |
22 | | */ |
23 | | |
24 | | #include <config.h> |
25 | | |
26 | | #include <stdlib.h> |
27 | | #include <string.h> |
28 | | #ifdef HAVE_STDBOOL_H |
29 | | # include <stdbool.h> |
30 | | #else |
31 | | # include <compat/stdbool.h> |
32 | | #endif |
33 | | #include <errno.h> |
34 | | #include <fcntl.h> |
35 | | #include <unistd.h> |
36 | | |
37 | | #include <sudo_compat.h> |
38 | | #include <sudo_util.h> |
39 | | #include <sudo_debug.h> |
40 | | |
41 | | bool |
42 | | sudo_lock_file_v1(int fd, int type) |
43 | 0 | { |
44 | 0 | return sudo_lock_region_v1(fd, type, 0); |
45 | 0 | } |
46 | | |
47 | | /* |
48 | | * Lock/unlock all or part of a file. |
49 | | */ |
50 | | #ifdef HAVE_LOCKF |
51 | | bool |
52 | | sudo_lock_region_v1(int fd, int type, off_t len) |
53 | 0 | { |
54 | 0 | int op, rc; |
55 | 0 | off_t oldpos = -1; |
56 | 0 | debug_decl(sudo_lock_region, SUDO_DEBUG_UTIL); |
57 | |
|
58 | 0 | switch (type) { |
59 | 0 | case SUDO_LOCK: |
60 | 0 | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: lock %d:%lld", |
61 | 0 | __func__, fd, (long long)len); |
62 | 0 | op = F_LOCK; |
63 | 0 | break; |
64 | 0 | case SUDO_TLOCK: |
65 | 0 | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: tlock %d:%lld", |
66 | 0 | __func__, fd, (long long)len); |
67 | 0 | op = F_TLOCK; |
68 | 0 | break; |
69 | 0 | case SUDO_UNLOCK: |
70 | 0 | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: unlock %d:%lld", |
71 | 0 | __func__, fd, (long long)len); |
72 | 0 | op = F_ULOCK; |
73 | | /* Must seek to start of file to unlock the entire thing. */ |
74 | 0 | if (len == 0 && (oldpos = lseek(fd, 0, SEEK_CUR)) != -1) { |
75 | 0 | if (lseek(fd, 0, SEEK_SET) == -1) { |
76 | 0 | sudo_debug_printf( |
77 | 0 | SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, |
78 | 0 | "unable to seek to beginning"); |
79 | 0 | } |
80 | 0 | } |
81 | 0 | break; |
82 | 0 | default: |
83 | 0 | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: bad lock type %d", |
84 | 0 | __func__, type); |
85 | 0 | errno = EINVAL; |
86 | 0 | debug_return_bool(false); |
87 | 0 | } |
88 | 0 | rc = lockf(fd, op, len); |
89 | 0 | if (oldpos != -1) { |
90 | 0 | if (lseek(fd, oldpos, SEEK_SET) == -1) { |
91 | 0 | sudo_debug_printf( |
92 | 0 | SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, |
93 | 0 | "unable to restore offset"); |
94 | 0 | } |
95 | 0 | } |
96 | | debug_return_bool(rc == 0); |
97 | 0 | } |
98 | | #else |
99 | | bool |
100 | | sudo_lock_region_v1(int fd, int type, off_t len) |
101 | | { |
102 | | struct flock lock; |
103 | | int func; |
104 | | debug_decl(sudo_lock_file, SUDO_DEBUG_UTIL); |
105 | | |
106 | | switch (type) { |
107 | | case SUDO_LOCK: |
108 | | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: lock %d:%lld", |
109 | | __func__, fd, (long long)len); |
110 | | lock.l_type = F_WRLCK; |
111 | | func = F_SETLKW; |
112 | | break; |
113 | | case SUDO_TLOCK: |
114 | | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: tlock %d:%lld", |
115 | | __func__, fd, (long long)len); |
116 | | lock.l_type = F_WRLCK; |
117 | | func = F_SETLK; |
118 | | break; |
119 | | case SUDO_UNLOCK: |
120 | | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: unlock %d:%lld", |
121 | | __func__, fd, (long long)len); |
122 | | lock.l_type = F_UNLCK; |
123 | | func = F_SETLK; |
124 | | break; |
125 | | default: |
126 | | sudo_debug_printf(SUDO_DEBUG_INFO, "%s: bad lock type %d", |
127 | | __func__, type); |
128 | | errno = EINVAL; |
129 | | debug_return_bool(false); |
130 | | } |
131 | | lock.l_start = 0; |
132 | | lock.l_len = len; |
133 | | lock.l_pid = 0; |
134 | | lock.l_whence = len ? SEEK_CUR : SEEK_SET; |
135 | | |
136 | | debug_return_bool(fcntl(fd, func, &lock) == 0); |
137 | | } |
138 | | #endif |