]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/auth.c
Tru64 patch (Burkhard Schmidt)
[netatalk.git] / etc / afpd / auth.c
index e302e2643bddab88ae0e5c8760877ba0b5f442d5..e3d76d18bb29f61fa3e532717db74e42ed9c027a 100644 (file)
@@ -1,11 +1,19 @@
 /*
+ * $Id: auth.c,v 1.16 2001-06-25 15:18:01 rufustfirefly Exp $
+ *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif /* HAVE_UNISTD_H */
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 
 #ifdef SHADOWPW
 #include <shadow.h>
-#endif
+#endif /* SHADOWPW */
 
 #include <pwd.h>
 #include <grp.h>
 #include <syslog.h>
 
+#ifdef TRU64
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <sia.h>
+#include <siad.h>
+
+extern void afp_get_cmdline( int *ac, char ***av );
+#endif /* TRU64 */
+
 #include "globals.h"
 #include "auth.h"
 #include "uam_auth.h"
@@ -65,12 +82,6 @@ static struct uam_obj uam_changepw = {"", "", 0, {{NULL}}, &uam_changepw,
 static struct uam_obj *afp_uam = NULL;
 
 
-/* Variables for CAP style printer authentication */
-#ifdef CAPDIR
-extern int addr_net, addr_node, addr_uid;
-extern char addr_name[32];
-#endif /* CAPDIR */
-
 void status_versions( data )
     char       *data;
 {
@@ -132,14 +143,18 @@ static int send_reply(const AFPObj *obj, const int err)
 
   obj->reply(obj->handle, err);
   obj->exit(0);
+
+  return AFP_OK;
 }
 
 static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void))
 {
-#ifdef CAPDIR
-    char nodename[256];
-    FILE *fp;
-#endif /* CAPDIR */
+#ifdef ADMIN_GRP
+    int admin = 0;
+#endif ADMIN_GRP
+
+    /* UAM had syslog control; afpd needs to reassert itself */
+    openlog( "afpd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
 
     if ( pwd->pw_uid == 0 ) {  /* don't allow root login */
        syslog( LOG_ERR, "login: root login denied!" );
@@ -149,41 +164,125 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void))
     syslog( LOG_INFO, "login %s (uid %d, gid %d)", pwd->pw_name,
            pwd->pw_uid, pwd->pw_gid );
 
-#ifdef CAPDIR
-    if(addr_net && addr_node) { /* Do we have a valid Appletalk address? */
-       addr_uid = pwd->pw_uid;
-       strncpy(addr_name, pwd->pw_name, 32);
-       sprintf(nodename, "%s/net%d.%dnode%d", CAPDIR, addr_net / 256, addr_net % 256, addr_node);
-       syslog (LOG_INFO, "registering %s (uid %d) on %u.%u as %s",
-                       addr_name, addr_uid, addr_net, addr_node, nodename);
-       fp = fopen(nodename, "w");
-       fprintf(fp, "%s\n", addr_name);
-       fclose(fp);
-    }
-#endif /* CAPDIR */
+    if (obj->proto == AFPPROTO_ASP) {
+      ASP asp = obj->handle;
+      int addr_net = ntohs( asp->asp_sat.sat_addr.s_net );
+      int addr_node  = asp->asp_sat.sat_addr.s_node;
+
+      if (obj->options.authprintdir) {
+       if(addr_net && addr_node) { /* Do we have a valid Appletalk address? */
+         char nodename[256];
+         FILE *fp;
+         struct stat stat_buf;
+
+         sprintf(nodename, "%s/net%d.%dnode%d", obj->options.authprintdir, 
+               addr_net / 256, addr_net % 256, addr_node);
+         syslog (LOG_INFO, "registering %s (uid %d) on %u.%u as %s",
+                       pwd->pw_name, pwd->pw_uid, addr_net, addr_node, nodename);
+
+         if (stat(nodename, &stat_buf) == 0) { /* file exists */
+           if (S_ISREG(stat_buf.st_mode)) { /* normal file */
+               unlink(nodename);
+               fp = fopen(nodename, "w");
+               fprintf(fp, "%s\n", pwd->pw_name);
+               fclose(fp);
+               chown( nodename, pwd->pw_uid, -1 );
+           } else { /* somebody is messing with us */
+               syslog( LOG_ERR, "print authfile %s is not a normal file, it will not be modified", nodename );
+           }
+         } else { /* file 'nodename' does not exist */
+           fp = fopen(nodename, "w");
+           fprintf(fp, "%s\n", pwd->pw_name);
+           fclose(fp);
+           chown( nodename, pwd->pw_uid, -1 );
+         }
+       } /* if (addr_net && addr_node ) */
+      } /* if (options->authprintdir) */
+    } /* if (obj->proto == AFPPROTO_ASP) */
 
     if (initgroups( pwd->pw_name, pwd->pw_gid ) < 0) {
 #ifdef RUN_AS_USER
       syslog(LOG_INFO, "running with uid %d", geteuid());
-#else
+#else /* RUN_AS_USER */
       syslog(LOG_ERR, "login: %m");
       return AFPERR_BADUAM;
-#endif
-    }
-    
-    if (setegid( pwd->pw_gid ) < 0 || seteuid( pwd->pw_uid ) < 0) {
-       syslog( LOG_ERR, "login: %m" );
-       return AFPERR_BADUAM;
+#endif /* RUN_AS_USER */
+
     }
 
+    /* Basically if the user is in the admin group, we stay root */
+
     if (( ngroups = getgroups( NGROUPS, groups )) < 0 ) {
        syslog( LOG_ERR, "login: getgroups: %m" );
        return AFPERR_BADUAM;
     }
+#ifdef ADMIN_GRP
+#ifdef DEBUG
+    syslog(LOG_INFO, "obj->options.admingid == %d", obj->options.admingid);
+#endif /* DEBUG */
+    if (obj->options.admingid != 0) {
+       int i;
+       for (i = 0; i < ngroups; i++) {
+           if (groups[i] == obj->options.admingid) admin = 1;
+        }
+    }
+    if (admin) syslog( LOG_INFO, "admin login -- %s", pwd->pw_name );
+    if (!admin)
+#endif /* DEBUG */
+#ifdef TRU64
+    {
+        struct DSI *dsi = obj->handle;
+        struct hostent *hp;
+        char *clientname;
+        int argc;
+        char **argv;
+        char hostname[256];
+
+        afp_get_cmdline( &argc, &argv );
+
+        hp = gethostbyaddr( (char *) &dsi->client.sin_addr,
+                            sizeof( struct in_addr ),
+                            dsi->client.sin_family );
+
+        if( hp )
+            clientname = hp->h_name;
+        else
+            clientname = inet_ntoa( dsi->client.sin_addr );
+
+        sprintf( hostname, "%s@%s", pwd->pw_name, clientname );
+
+        if( sia_become_user( NULL, argc, argv, hostname, pwd->pw_name,
+                             NULL, FALSE, NULL, NULL,
+                             SIA_BEU_REALLOGIN ) != SIASUCCESS )
+            return AFPERR_BADUAM;
+
+        syslog( LOG_INFO, "session from %s (%s)", hostname,
+                inet_ntoa( dsi->client.sin_addr ) );
+
+        if (setegid( pwd->pw_gid ) < 0 || seteuid( pwd->pw_uid ) < 0) {
+            syslog( LOG_ERR, "login: %m" );
+            return AFPERR_BADUAM;
+        }
+    }
+#else /* TRU64 */
+       if (setegid( pwd->pw_gid ) < 0 || seteuid( pwd->pw_uid ) < 0) {
+           syslog( LOG_ERR, "login: %m" );
+           return AFPERR_BADUAM;
+       }
+#endif /* TRU64 */
+
+    /* There's probably a better way to do this, but for now, we just 
+       play root */
+
+#ifdef ADMIN_GRP
+    if (admin) uuid = 0;
+    else
+#endif /* ADMIN_GRP */
     uuid = pwd->pw_uid;
 
     afp_switch = postauth_switch;
     obj->logout = logout;
+
     return( AFP_OK );
 }
 
@@ -221,7 +320,7 @@ int afp_login(obj, ibuf, ibuflen, rbuf, rbuflen )
     i = afp_uam->u.uam_login.login(obj, &pwd, ibuf, ibuflen, rbuf, rbuflen);
     if (i || !pwd) 
       return send_reply(obj, i);
-      
+
     return send_reply(obj, login(obj, pwd, afp_uam->u.uam_login.logout));
 }
 
@@ -256,6 +355,7 @@ int afp_logout(obj, ibuf, ibuflen, rbuf, rbuflen)
 {
   syslog(LOG_INFO, "logout %s", obj->username);
   obj->exit(0);
+  return AFP_OK;
 }
 
 
@@ -420,12 +520,24 @@ int auth_load(const char *path, const char *list)
 
   while (p) {
     strncpy(name + len, p, sizeof(name) - len);
+    syslog(LOG_DEBUG, "uam : Loading (%s)", name);
+    /*
     if ((stat(name, &st) == 0) && (mod = uam_load(name, p))) {
-      uam_attach(&uam_modules, mod);
-      syslog(LOG_INFO, "uam: %s loaded", p);
+    */
+    if (stat(name, &st) == 0) {
+      if ((mod = uam_load(name, p))) {
+       uam_attach(&uam_modules, mod);
+       syslog(LOG_INFO, "uam: %s loaded", p);
+      } else {
+       syslog(LOG_INFO, "uam: %s load failure",p);
+      }
+    } else {
+      syslog(LOG_INFO, "uam: uam not found (status=%d)", stat(name, &st));
     }
     p = strtok(NULL, ",");
   }
+
+  return 0;
 }
 
 /* get rid of all of the uams */