Added the security changes suggested by Andrew - become the
authorJeremy Allison <jra@samba.org>
Thu, 12 Nov 1998 03:06:00 +0000 (03:06 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 12 Nov 1998 03:06:00 +0000 (03:06 +0000)
user that authenticated to swat permanently (if not root).
Jeremy.

source/include/proto.h
source/web/cgi.c
source/web/swat.c

index 5c0efaf93c0bd01478a50278dcc65656238b9214..24d4040c3ceea7200da4d7ede431c532c6c8c14b 100644 (file)
@@ -2657,4 +2657,5 @@ void status_page(void);
 
 /*The following definitions come from  web/swat.c  */
 
+BOOL become_user_permanently(uid_t uid, gid_t gid);
 #endif /* _PROTO_H_ */
index 5415abf6b3e2c00a5e3309133067a77dcfe54183..9b5cf2158cc5effa2f93904a9417123aaf4f20ca 100644 (file)
@@ -293,29 +293,83 @@ static void base64_decode(char *s)
 /***************************************************************************
 handle a http authentication line
   ***************************************************************************/
-static int cgi_handle_authorization(char *line)
+static BOOL cgi_handle_authorization(char *line)
 {
-       char *p, *user, *pass;
+       char *p, *user, *user_pass;
+       struct passwd *pass = NULL;
+       int ret = False;
 
        if (strncasecmp(line,"Basic ", 6)) {
                cgi_setup_error("401 Bad Authorization", "", 
                                "Only basic authorization is understood");
+               return False;
        }
        line += 6;
        while (line[0] == ' ') line++;
        base64_decode(line);
        if (!(p=strchr(line,':'))) {
+               /*
+                * Always give the same error so a cracker
+                * cannot tell why we fail.
+                */
                cgi_setup_error("401 Bad Authorization", "", 
                                "username/password must be supplied");
+               return False;
        }
        *p = 0;
        user = line;
-       pass = p+1;
+       user_pass = p+1;
+
+       /*
+        * Try and get the user from the UNIX password file.
+        */
+
+       if(!(pass = Get_Pwnam(user,False))) {
+               /*
+                * Always give the same error so a cracker
+                * cannot tell why we fail.
+                */
+               cgi_setup_error("401 Bad Authorization", "",
+                               "username/password must be supplied");
+               return False;
+       }
+
+       /*
+        * Validate the password they have given.
+        */
+
+       if((ret = pass_check(user, user_pass, strlen(user_pass), NULL, NULL)) == True) {
+
+               /*
+                * Password was ok.
+                */
+
+               if(pass->pw_uid != 0) {
+                       /*
+                        * We have not authenticated as root,
+                        * become the user *permanently*.
+                        */
+                       if(!become_user_permanently(pass->pw_uid, pass->pw_gid)) {
+                               /*
+                                * Always give the same error so a cracker
+                                * cannot tell why we fail.
+                                */
+                               cgi_setup_error("401 Bad Authorization", "",
+                       "username/password must be supplied");
+                       return False;
+                       }
+
+                       /*
+                        * On exit from here we are the authenticated
+                        * user - no way back.
+                        */
+               }
 
-       /* Save the users name */
-       C_user = strdup(user);
+               /* Save the users name */
+               C_user = strdup(user);
+       }
 
-       return pass_check(user, pass, strlen(pass), NULL, NULL);
+       return ret;
 }
 
 /***************************************************************************
@@ -323,7 +377,7 @@ is this root?
   ***************************************************************************/
 BOOL am_root(void)
 {
-       if ((C_user) && (strcmp(C_user,"root") == 0)) {
+       if (geteuid() == 0) {
                return( True);
        } else {
                return( False);
@@ -393,7 +447,7 @@ run as a true cgi program by a web browser or is itself a mini web server
   ***************************************************************************/
 void cgi_setup(char *rootdir, int auth_required)
 {
-       int authenticated = 0;
+       BOOL authenticated = False;
        char line[1024];
        char *url=NULL;
        char *p;
index 1030689f18df94dfa30bbb7245967d5231db55d9..1ab90a3a3ddf6e8125a31f7c9e016efa6daa15d7 100644 (file)
@@ -771,74 +771,62 @@ static BOOL talk_to_smbpasswd(char *old, char *new)
 }
 
 /****************************************************************************
-  become the specified uid
+  become the specified uid - permanently !
 ****************************************************************************/
-static BOOL become_uid(uid_t uid)
+
+BOOL become_user_permanently(uid_t uid, gid_t gid)
 {
-#ifdef HAVE_TRAPDOOR_UID
-#ifdef HAVE_SETUIDX
-       /* AIX3 has setuidx which is NOT a trapoor function (tridge) */
-       if (setuidx(ID_EFFECTIVE, uid) != 0) {
-               if (seteuid(uid) != 0) {
-                       printf("<p> Can't set uid %d (setuidx)\n", (int)uid);
-                       return False;
-               }
-       }
-#endif
-#endif
 
-#ifdef HAVE_SETRESUID
-       if (setresuid(-1,uid,-1) != 0)
-#else
-       if ((seteuid(uid) != 0) && (setuid(uid) != 0))
-#endif
-       {
-               printf("<p> Couldn't set uid %d currently set to (uid %d, euid %d)\n",
-                       (int)uid,(int)getuid(), (int)geteuid());
-               if (uid > (uid_t)32000) {
-                       printf("<p> Looks like your OS doesn't like high uid values - try using a different account\n");
+    if (geteuid() != 0) {
+        return(True);
+    }
 
-               }
-               return(False);
-       }
+    /* now completely lose our privilages. This is a fairly paranoid
+    way of doing it, but it does work on all systems that I know of */
 
-       if (((uid == (uid_t)-1) || ((sizeof(uid_t) == 2) && (uid == 65535))) &&
-            (geteuid() != uid)) {
-               printf("<p> Invalid uid -1. perhaps you have a account with uid 65535?\n");
-               return(False);
-       }
+#ifdef HAVE_SETRESUID
+       /*
+        * Firstly ensure all our uids are set to root.
+        */
+    setresgid(0,0,0);
+    setresuid(0,0,0);
 
-       return(True);
-}
+       /*
+        * Now ensure we change all our gids.
+        */
+    setresgid(gid,gid,gid);
 
-/****************************************************************************
-  become the specified gid
-****************************************************************************/
-static BOOL become_gid(gid_t gid)
-{
-#ifdef HAVE_SETRESUID
-       if (setresgid(-1,gid,-1) != 0)
+       /*
+        * Now ensure all the uids are the user.
+        */
+    setresuid(uid,uid,uid);
 #else
-       if (setgid(gid) != 0)
+       /*
+        * Firstly ensure all our uids are set to root.
+        */
+    setuid(0);
+    seteuid(0);
+
+       /*
+        * Now ensure we change all our gids.
+        */
+    setgid(gid);
+    setegid(gid);
+
+       /*
+        * Now ensure all the uids are the user.
+        */
+    setuid(uid);
+    seteuid(uid);
 #endif
-       {
-               printf("<p> Couldn't set gid %d currently set to (gid %d, egid %d)\n",
-                 (int)gid,(int)getgid(),(int)getegid());
-               if (gid > 32000) {
-                       printf("<p> Looks like your OS doesn't like high gid values - try using a different account\n");
-               }
-               return(False);
-       }
 
-       return(True);
-}
+    if (getuid() != uid || geteuid() != uid ||
+        getgid() != gid || getegid() != gid) {
+        /* We failed to lose our privilages. */
+        return False;
+    }
 
-/****************************************************************************
-  become the specified uid and gid
-****************************************************************************/
-static BOOL become_id(uid_t uid,gid_t gid)
-{
-       return(become_gid(gid) && become_uid(uid));
+       return(True);
 }
 
 /****************************************************************************
@@ -881,19 +869,6 @@ static void chg_passwd(void)
                }
        }
 
-       /* Get the UID/GID of the user, and become that user  */
-       if (am_root() == False) {
-               pass = Get_Pwnam(cgi_variable(user),True);
-               if (pass == NULL) {
-                       printf("<p> User uid unknown     \n");
-               } else {
-                       if (become_id(pass->pw_uid, pass->pw_gid) == False) {
-                               printf("<p> uid/gid set failed \n");
-                               return;
-                       }
-               }
-       }
-
 #ifdef SWAT_DEBUG
        if (pass) printf("<p> User uid %d  gid %d \n", pass->pw_uid, pass->pw_gid);
        printf("<p> Processes uid %d, euid %d, gid %d, egid %d \n",getuid(),geteuid(),getgid(),getegid());
@@ -1138,4 +1113,3 @@ static void printers_page(void)
        print_footer();
        return 0;
 }
-