Check on shutdown if caller really was root. In secure mode get uid
authordrepper <drepper>
Fri, 11 Jun 1999 20:56:09 +0000 (20:56 +0000)
committerdrepper <drepper>
Fri, 11 Jun 1999 20:56:09 +0000 (20:56 +0000)
of caller.

nscd/connections.c

index ca139fb..3f05d68 100644 (file)
@@ -195,7 +195,7 @@ close_sockets (void)
 
 /* Handle new request.  */
 static void
-handle_request (int fd, request_header *req, void *key)
+handle_request (int fd, request_header *req, void *key, uid_t uid)
 {
   if (debug_level > 0)
     dbg_log (_("handle_request: request received (Version = %d)"),
@@ -251,7 +251,7 @@ cannot handle old request version %d; current version is %d"),
 
       /* See whether we can handle it from the cache.  */
       cached = (struct hashentry *) cache_search (req->type, key, req->key_len,
-                                                 db);
+                                                 db, uid);
       if (cached != NULL)
        {
          /* Hurray it's in the cache.  */
@@ -279,35 +279,35 @@ cannot handle old request version %d; current version is %d"),
   switch (req->type)
     {
     case GETPWBYNAME:
-      addpwbyname (&dbs[serv2db[req->type]], fd, req, key);
+      addpwbyname (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETPWBYUID:
-      addpwbyuid (&dbs[serv2db[req->type]], fd, req, key);
+      addpwbyuid (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETGRBYNAME:
-      addgrbyname (&dbs[serv2db[req->type]], fd, req, key);
+      addgrbyname (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETGRBYGID:
-      addgrbygid (&dbs[serv2db[req->type]], fd, req, key);
+      addgrbygid (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETHOSTBYNAME:
-      addhstbyname (&dbs[serv2db[req->type]], fd, req, key);
+      addhstbyname (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETHOSTBYNAMEv6:
-      addhstbynamev6 (&dbs[serv2db[req->type]], fd, req, key);
+      addhstbynamev6 (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETHOSTBYADDR:
-      addhstbyaddr (&dbs[serv2db[req->type]], fd, req, key);
+      addhstbyaddr (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETHOSTBYADDRv6:
-      addhstbyaddrv6 (&dbs[serv2db[req->type]], fd, req, key);
+      addhstbyaddrv6 (&dbs[serv2db[req->type]], fd, req, key, uid);
       break;
 
     case GETSTAT:
@@ -315,7 +315,24 @@ cannot handle old request version %d; current version is %d"),
       break;
 
     case SHUTDOWN:
-      termination_handler (0);
+      /* Accept shutdown only from root */
+      if (secure_in_use && uid == 0)
+       termination_handler (0);
+      else
+       {
+         struct ucred caller;
+         int optlen = sizeof (caller);
+
+         if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) < 0)
+           {
+             char buf[256];
+
+             dbg_log (_("error getting callers id: %s"),
+                      strerror_r (errno, buf, sizeof (buf)));
+           }
+         else if (caller.uid == 0)
+           termination_handler (0);
+       }
       break;
 
     default:
@@ -362,6 +379,7 @@ nscd_run (void *p)
          int fd = accept (conn.fd, NULL, NULL);
          request_header req;
          char buf[256];
+         uid_t uid = 0;
 
          if (fd < 0)
            {
@@ -380,6 +398,25 @@ nscd_run (void *p)
              continue;
            }
 
+         if (secure_in_use)
+           {
+             struct ucred caller;
+             int optlen = sizeof (caller);
+
+             if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED,
+                             &caller, &optlen) < 0)
+               {
+                 dbg_log (_("error getting callers id: %s"),
+                          strerror_r (errno, buf, sizeof (buf)));
+                 close (fd);
+                 continue;
+               }
+
+             if (req.type < GETPWBYNAME || req.type >= LASTREQ
+                 || secure[serv2db[req.type]])
+               uid = caller.uid;
+           }
+
          /* It should not be possible to crash the nscd with a silly
             request (i.e., a terribly large key.  We limit the size
             to 1kb.  */
@@ -404,7 +441,7 @@ nscd_run (void *p)
                }
 
              /* Phew, we got all the data, now process it.  */
-             handle_request (fd, &req, keybuf);
+             handle_request (fd, &req, keybuf, uid);
 
              /* We are done.  */
              close (fd);