]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/auth.c
Spotlight: use async Tracker SPARQL API
[netatalk.git] / etc / afpd / auth.c
index d6054f54b6360a2c232c589c51f28a6c2e25ff78..dc4dd8bce6c27fe36afe8abc4f912232e388ef03 100644 (file)
@@ -39,6 +39,9 @@ extern void afp_get_cmdline( int *ac, char ***av );
 #include <atalk/server_ipc.h>
 #include <atalk/uuid.h>
 #include <atalk/globals.h>
+#include <atalk/fce_api.h>
+#include <atalk/spotlight.h>
+#include <atalk/unix.h>
 
 #include "auth.h"
 #include "uam_auth.h"
@@ -50,7 +53,6 @@ extern void afp_get_cmdline( int *ac, char ***av );
 #include "acls.h"
 #endif
 
-int afp_version = 11;
 static int afp_version_index;
 static struct uam_mod uam_modules = {NULL, NULL, &uam_modules, &uam_modules};
 static struct uam_obj uam_login = {"", "", 0, {{NULL, NULL, NULL, NULL }}, &uam_login,
@@ -146,7 +148,7 @@ static int afp_null_nolog(AFPObj *obj _U_, char *ibuf _U_, size_t ibuflen _U_,
     return( AFPERR_NOOP );
 }
 
-static int set_auth_switch(int expired)
+static int set_auth_switch(const AFPObj *obj, int expired)
 {
     int i;
 
@@ -167,8 +169,9 @@ static int set_auth_switch(int expired)
     }
     else {
         afp_switch = postauth_switch;
-        switch (afp_version) {
+        switch (obj->afp_version) {
 
+        case 34:
         case 33:
         case 32:
 #ifdef HAVE_ACLS
@@ -184,7 +187,9 @@ static int set_auth_switch(int expired)
         case 31:
             uam_afpserver_action(AFP_SYNCDIR, UAM_AFPSERVER_POSTAUTH, afp_syncdir, NULL);
             uam_afpserver_action(AFP_SYNCFORK, UAM_AFPSERVER_POSTAUTH, afp_syncfork, NULL);
-            uam_afpserver_action(AFP_SPOTLIGHT_PRIVATE, UAM_AFPSERVER_POSTAUTH, afp_null_nolog, NULL);
+#ifdef HAVE_TRACKER
+            uam_afpserver_action(AFP_SPOTLIGHT_PRIVATE, UAM_AFPSERVER_POSTAUTH, afp_spotlight_rpc, NULL);
+#endif
             uam_afpserver_action(AFP_ENUMERATE_EXT2, UAM_AFPSERVER_POSTAUTH, afp_enumerate_ext2, NULL);
 
         case 30:
@@ -211,23 +216,6 @@ static int set_auth_switch(int expired)
     return AFP_OK;
 }
 
-#define GROUPSTR_BUFSIZE 1024
-static 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;
-}
-
 static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expired)
 {
 #ifdef ADMIN_GRP
@@ -239,35 +227,16 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
         return AFPERR_NOTAUTH;
     }
 
-    LOG(log_note, logtype_afpd, "%s Login by %s",
-        afp_versions[afp_version_index].av_name, pwd->pw_name);
-
-    if (initgroups( pwd->pw_name, pwd->pw_gid ) < 0) {
-#ifdef RUN_AS_USER
-        LOG(log_info, logtype_afpd, "running with uid %d", geteuid());
-#else /* RUN_AS_USER */
-        LOG(log_error, logtype_afpd, "login: %s", strerror(errno));
-        return AFPERR_BADUAM;
-#endif /* RUN_AS_USER */
-
+    if (obj->cnx_cnt > obj->cnx_max) {
+        LOG(log_error, logtype_dsi, "login: too many connections, limit: %d", obj->cnx_max);
+        return AFPERR_MAXSESS;
     }
 
-    /* Basically if the user is in the admin group, we stay root */
+    LOG(log_note, logtype_afpd, "Login by %s (%s)",
+        pwd->pw_name, afp_versions[afp_version_index].av_name);
 
-    if ((obj->ngroups = getgroups( 0, NULL )) < 0 ) {
-        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
+    if (set_groups(obj, pwd) != 0)
         return AFPERR_BADUAM;
-    }
-
-    if ( NULL == (obj->groups = calloc(obj->ngroups, sizeof(gid_t))) ) {
-        LOG(log_error, logtype_afpd, "login: %s calloc: %d", obj->ngroups);
-        return AFPERR_BADUAM;
-    }
-
-    if (( obj->ngroups = getgroups(obj->ngroups, obj->groups )) < 0 ) {
-        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
-        return AFPERR_BADUAM;
-    }
 
 #ifdef ADMIN_GRP
     LOG(log_debug, logtype_afpd, "obj->options.admingid == %d", obj->options.admingid);
@@ -336,11 +305,20 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
 #endif /* ADMIN_GRP */
         obj->uid = geteuid();
 
-    set_auth_switch(expired);
+    set_auth_switch(obj, expired);
     /* save our euid, we need it for preexec_close */
     obj->uid = geteuid();
     obj->logout = logout;
 
+    /* pam_umask or similar might have changed our umask */
+    (void)umask(obj->options.umask);
+
+    /* Some PAM module might have reset our signal handlers and timer, so we need to reestablish them */
+    afp_over_dsi_sighandlers(obj);
+
+    /* Send FCE login event */
+    fce_register(obj, FCE_LOGIN, "", NULL);
+
     return( AFP_OK );
 }
 
@@ -370,6 +348,7 @@ int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen
         if (dsi->flags & DSI_EXTSLEEP) {
             LOG(log_note, logtype_afpd, "afp_zzz: waking up from extended sleep");
             dsi->flags &= ~(DSI_SLEEPING | DSI_EXTSLEEP);
+            ipc_child_state(obj, DSI_RUNNING);
         }
     } else {
         /* sleep request */
@@ -377,8 +356,10 @@ int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen
         if (data & AFPZZZ_EXT_SLEEP) {
             LOG(log_note, logtype_afpd, "afp_zzz: entering extended sleep");
             dsi->flags |= DSI_EXTSLEEP;
+            ipc_child_state(obj, DSI_EXTSLEEP);
         } else {
             LOG(log_note, logtype_afpd, "afp_zzz: entering normal sleep");
+            ipc_child_state(obj, DSI_SLEEPING);
         }
     }
 
@@ -631,7 +612,7 @@ static int get_version(AFPObj *obj, char *ibuf, size_t ibuflen, size_t len)
     num = sizeof( afp_versions ) / sizeof( afp_versions[ 0 ]);
     for ( i = 0; i < num; i++ ) {
         if ( strncmp( ibuf, afp_versions[ i ].av_name , len ) == 0 ) {
-            afp_version = afp_versions[ i ].av_number;
+            obj->afp_version = afp_versions[ i ].av_number;
             afp_version_index = i;
             break;
         }
@@ -640,7 +621,7 @@ static int get_version(AFPObj *obj, char *ibuf, size_t ibuflen, size_t len)
         return AFPERR_BADVERS ;
 
     /* FIXME Hack */
-    if (afp_version >= 30 && sizeof(off_t) != 8) {
+    if (obj->afp_version >= 30 && sizeof(off_t) != 8) {
         LOG(log_error, logtype_afpd, "get_version: no LARGE_FILE support recompile!" );
         return AFPERR_BADVERS ;
     }
@@ -852,10 +833,14 @@ int afp_logout(AFPObj *obj, char *ibuf _U_, size_t ibuflen  _U_, char *rbuf  _U_
     DSI *dsi = (DSI *)(obj->dsi);
 
     LOG(log_note, logtype_afpd, "AFP logout by %s", obj->username);
-    of_close_all_forks();
-    close_all_vol();
+    of_close_all_forks(obj);
+    close_all_vol(obj);
     dsi->flags = DSI_AFP_LOGGED_OUT;
     *rbuflen = 0;
+
+    /* Send FCE login event */
+    fce_register(obj, FCE_LOGOUT, "", NULL);
+
     return AFP_OK;
 }
 
@@ -892,7 +877,7 @@ int afp_changepw(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rb
     if ((len + 1) & 1) /* pad byte */
         ibuf++;
 
-    if ( afp_version < 30) {
+    if (obj->afp_version < 30) {
         len = (unsigned char) *ibuf++;
         if ( len > sizeof(username) - 1) {
             return AFPERR_PARAM;
@@ -907,7 +892,7 @@ int afp_changepw(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rb
         if ( ibuf[0] != '\0' || ibuf[1] != '\0')
             return AFPERR_PARAM;
         ibuf += 2;
-        len = MIN(sizeof(username), strlen(obj->username));
+        len = MIN(sizeof(username) - 1, strlen(obj->username));
         memcpy(username, obj->username, len);
         username[ len ] = '\0';
     }
@@ -929,7 +914,7 @@ int afp_changepw(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rb
         (ret == AFPERR_AUTHCONT) ? "continued" :
         (ret ? "failed" : "succeeded"));
     if ( ret == AFP_OK )
-        set_auth_switch(0);
+        set_auth_switch(obj, 0);
 
     return ret;
 }
@@ -1044,9 +1029,9 @@ int auth_register(const int type, struct uam_obj *uam)
 }
 
 /* load all of the modules */
-int auth_load(const char *path, const char *list)
+int auth_load(AFPObj *obj, const char *path, const char *list)
 {
-    char name[MAXPATHLEN + 1], buf[MAXPATHLEN + 1], *p;
+    char name[MAXPATHLEN + 1], buf[MAXPATHLEN + 1], *p, *last;
     struct uam_mod *mod;
     struct stat st;
     size_t len;
@@ -1054,8 +1039,10 @@ int auth_load(const char *path, const char *list)
     if (!path || !*path || !list || (len = strlen(path)) > sizeof(name) - 2)
         return -1;
 
+    LOG(log_debug, logtype_afpd, "auth_load: %s, %s", path, list);
+
     strlcpy(buf, list, sizeof(buf));
-    if ((p = strtok(buf, ",")) == NULL)
+    if ((p = strtok_r(buf, ", ", &last)) == NULL)
         return -1;
 
     strcpy(name, path);
@@ -1071,7 +1058,7 @@ int auth_load(const char *path, const char *list)
           if ((stat(name, &st) == 0) && (mod = uam_load(name, p))) {
         */
         if (stat(name, &st) == 0) {
-            if ((mod = uam_load(name, p))) {
+            if ((mod = uam_load(obj, name, p))) {
                 uam_attach(&uam_modules, mod);
                 LOG(log_debug, logtype_afpd, "uam: %s loaded", p);
             } else {
@@ -1080,7 +1067,7 @@ int auth_load(const char *path, const char *list)
         } else {
             LOG(log_info, logtype_afpd, "uam: uam not found (status=%d)", stat(name, &st));
         }
-        p = strtok(NULL, ",");
+        p = strtok_r(NULL, ", ", &last);
     }
 
     return 0;