summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAndrew Clayton <a.clayton@nginx.com>2023-11-06 18:43:19 +0000
committerAndrew Clayton <a.clayton@nginx.com>2024-02-19 12:59:29 +0000
commit34b3a812b110e8fba0669fc843aebffddf89ab17 (patch)
tree114bfd95ed4b9fe38d4d48f519268ecc9f3c99e8 /src
parentbaff936be1b8bb9627deaef2af58d9aa398b7ca2 (diff)
downloadunit-34b3a812b110e8fba0669fc843aebffddf89ab17.tar.gz
unit-34b3a812b110e8fba0669fc843aebffddf89ab17.tar.bz2
Add nxt_file_chown()
This wraps chown(2) but takes the user/owner and group as strings. It's a little long winded as it uses the thread safe versions of getpwnam()/getgrname() which require a little more work. This function will be used by the following commit that allows to set the permissions of the Unix domain control socket. We need to cast uid & gid to long in the call to nxt_thread_log_alert() to appease clang-ast as it's adamant that uid/gid are unsigned ints, but chown(2) takes -1 for these values to indicate don't change this item, and it'd be nice to show them in the error message. Note that getpwnam()/getgrname() don't define "not found" as an error as per their man page The formulation given above under "RETURN VALUE" is from POSIX.1-2001. It does not call "not found" an error, and hence does not specify what value errno might have in this situation. But that makes it impossible to recognize errors. One might argue that according to POSIX errno should be left unchanged if an entry is not found. Experiments on var‐ ious UNIX-like systems show that lots of different values occur in this situation: 0, ENOENT, EBADF, ESRCH, EWOULDBLOCK, EPERM, and probably others. Thus if we log an error from these functions we can end up with the slightly humorous error message 2024/02/12 15:15:12 [alert] 99404#99404 getpwnam_r("noddy", ...) failed (0: Success) (User not found) while creating listening socket on unix:/opt/unit/control.unit.sock Reviewed-by: Zhidao Hong <z.hong@f5.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
Diffstat (limited to 'src')
-rw-r--r--src/nxt_file.c82
-rw-r--r--src/nxt_file.h2
2 files changed, 84 insertions, 0 deletions
diff --git a/src/nxt_file.c b/src/nxt_file.c
index 6f1a93e4..4047d9d7 100644
--- a/src/nxt_file.c
+++ b/src/nxt_file.c
@@ -326,6 +326,88 @@ nxt_file_set_access(nxt_file_name_t *name, nxt_file_access_t access)
nxt_int_t
+nxt_file_chown(nxt_file_name_t *name, const char *owner, const char *group)
+{
+ int err;
+ char *buf;
+ long bufsize;
+ gid_t gid = ~0;
+ uid_t uid = ~0;
+
+ if (owner == NULL && group == NULL) {
+ return NXT_OK;
+ }
+
+ if (owner != NULL) {
+ struct passwd pwd, *result;
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize == -1) {
+ bufsize = 32768;
+ }
+
+ buf = nxt_malloc(bufsize);
+ if (buf == NULL) {
+ return NXT_ERROR;
+ }
+
+ err = getpwnam_r(owner, &pwd, buf, bufsize, &result);
+ if (result == NULL) {
+ nxt_thread_log_alert("getpwnam_r(\"%s\", ...) failed %E %s",
+ owner, nxt_errno,
+ err == 0 ? "(User not found)" : "");
+ goto out_err_free;
+ }
+
+ uid = pwd.pw_uid;
+
+ nxt_free(buf);
+ }
+
+ if (group != NULL) {
+ struct group grp, *result;
+
+ bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (bufsize == -1) {
+ bufsize = 32768;
+ }
+
+ buf = nxt_malloc(bufsize);
+ if (buf == NULL) {
+ return NXT_ERROR;
+ }
+
+ err = getgrnam_r(group, &grp, buf, bufsize, &result);
+ if (result == NULL) {
+ nxt_thread_log_alert("getgrnam_r(\"%s\", ...) failed %E %s",
+ group, nxt_errno,
+ err == 0 ? "(Group not found)" : "");
+ goto out_err_free;
+ }
+
+ gid = grp.gr_gid;
+
+ nxt_free(buf);
+ }
+
+ if (nxt_fast_path(chown((const char *) name, uid, gid) == 0)) {
+ return NXT_OK;
+ }
+
+ nxt_thread_log_alert("chown(\"%FN\", %l, %l) failed %E", name,
+ owner != NULL ? (long) uid : -1,
+ group != NULL ? (long) gid : -1, nxt_errno);
+
+ return NXT_ERROR;
+
+out_err_free:
+ nxt_free(buf);
+
+ return NXT_ERROR;
+}
+
+
+nxt_int_t
nxt_file_rename(nxt_file_name_t *old_name, nxt_file_name_t *new_name)
{
int ret;
diff --git a/src/nxt_file.h b/src/nxt_file.h
index 97636db6..0c03a5f9 100644
--- a/src/nxt_file.h
+++ b/src/nxt_file.h
@@ -177,6 +177,8 @@ NXT_EXPORT nxt_int_t nxt_file_info(nxt_file_t *file, nxt_file_info_t *fi);
NXT_EXPORT nxt_int_t nxt_file_delete(nxt_file_name_t *name);
NXT_EXPORT nxt_int_t nxt_file_set_access(nxt_file_name_t *name,
nxt_file_access_t access);
+NXT_EXPORT nxt_int_t nxt_file_chown(nxt_file_name_t *name, const char *owner,
+ const char *group);
NXT_EXPORT nxt_int_t nxt_file_rename(nxt_file_name_t *old_name,
nxt_file_name_t *new_name);