]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/unix.c
Add advanced option "chmod request" controlling ACLs
[netatalk.git] / libatalk / util / unix.c
index 7c80e22d5d761085503fd990b05b63b38157a569..4572caddd454d36c1b0cd3e45b6b258b7aedadf3 100644 (file)
@@ -44,6 +44,7 @@
 #include <atalk/unix.h>
 #include <atalk/compat.h>
 #include <atalk/errchk.h>
+#include <atalk/acl.h>
 
 /* close all FDs >= a specified value */
 static void closeall(int fd)
@@ -262,11 +263,15 @@ int ochown(const char *path, uid_t owner, gid_t group, int options)
  * Options description:
  * O_NOFOLLOW: don't chmod() symlinks, do nothing, return 0
  * O_NETATALK_ACL: call chmod_acl() instead of chmod()
+ * O_IGNORE: ignore chmod() request, directly return 0
  */
 int ochmod(char *path, mode_t mode, const struct stat *st, int options)
 {
     struct stat sb;
 
+    if (options & O_IGNORE)
+        return 0;
+
     if (!st) {
         if (lstat(path, &sb) != 0)
             return -1;
@@ -436,7 +441,7 @@ char *realpath_safe(const char *path)
 
 #ifdef REALPATH_TAKES_NULL
     if ((resolved_path = realpath(path, NULL)) == NULL) {
-        LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
+        LOG(log_debug, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
         return NULL;
     }
     return resolved_path;
@@ -445,7 +450,7 @@ char *realpath_safe(const char *path)
         return NULL;
     if (realpath(path, resolved_path) == NULL) {
         free(resolved_path);
-        LOG(log_error, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
+        LOG(log_debug, logtype_afpd, "realpath() cannot resolve path \"%s\"", path);
         return NULL;
     }
     /* Safe some memory */
@@ -507,3 +512,45 @@ char *strtok_quote(char *s, const char *delim)
     }
     return token;
 }
+
+int set_groups(AFPObj *obj, struct passwd *pwd)
+{
+    if (initgroups(pwd->pw_name, pwd->pw_gid) < 0)
+        LOG(log_error, logtype_afpd, "initgroups(%s, %d): %s", pwd->pw_name, pwd->pw_gid, strerror(errno));
+
+    if ((obj->ngroups = getgroups(0, NULL)) < 0) {
+        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno));
+        return -1;
+    }
+
+    if (obj->groups)
+        free(obj->groups);
+    if (NULL == (obj->groups = calloc(obj->ngroups, sizeof(gid_t))) ) {
+        LOG(log_error, logtype_afpd, "login: %s calloc: %d", obj->ngroups);
+        return -1;
+    }
+
+    if ((obj->ngroups = getgroups(obj->ngroups, obj->groups)) < 0 ) {
+        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+#define GROUPSTR_BUFSIZE 1024
+const char *print_groups(int ngroups, gid_t *groups)
+{
+    static char groupsstr[GROUPSTR_BUFSIZE];
+    int i;
+    char *s = groupsstr;
+
+    if (ngroups == 0)
+        return "-";
+
+    for (i = 0; (i < ngroups) && (s < &groupsstr[GROUPSTR_BUFSIZE]); i++) {
+        s += snprintf(s, &groupsstr[GROUPSTR_BUFSIZE] - s, " %u", groups[i]);
+    }
+
+    return groupsstr;
+}