components/net-snmp/patches/058.22761186.patch
author pkidd <patrick.kidd@oracle.com>
Wed, 09 Nov 2016 08:50:05 -0800
branchs11u3-sru
changeset 7274 9741a2ade01f
parent 6733 0901797054b4
permissions -rw-r--r--
25065852 23093717/22067764 need to be backed out of the Userland gate: causes 25064383

The patch has been taken from community and modifies directory creation code to happen after the domain selection code so that the directory creation code knows what directory to create.

The details can be found in the following location
https://sourceforge.net/p/net-snmp/code/ci/b066a45975a505545b064c5492f7d7fe0a7623dd/

--- net-snmp-5.4.1/agent/mibgroup/agentx/master.c	2007-01-22 08:19:47.000000000 -0800
+++ copy_net-snmp-5.4.1/agent/mibgroup/agentx/master.c	2016-01-30 01:41:53.175843516 -0800
@@ -60,13 +60,6 @@
     char *agentx_sockets;
     char *cp1;
 
-#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
-    int agentx_dir_perm;
-    int agentx_sock_perm;
-    int agentx_sock_user;
-    int agentx_sock_group;
-#endif
-
     if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE) != MASTER_AGENT)
         return;
 
@@ -89,7 +82,6 @@
         agentx_sockets = strdup("");
     }
 
-
     DEBUGMSGTL(("agentx/master", "initializing...\n"));
     snmp_sess_init(&sess);
     sess.version = AGENTX_VERSION_1;
@@ -98,6 +90,18 @@
                                       NETSNMP_DS_AGENT_AGENTX_TIMEOUT);
     sess.retries = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
                                       NETSNMP_DS_AGENT_AGENTX_RETRIES);
+
+#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
+    {
+       int agentx_dir_perm =
+           netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+                              NETSNMP_DS_AGENT_X_DIR_PERM);
+       if (agentx_dir_perm == 0)
+           agentx_dir_perm = NETSNMP_AGENT_DIRECTORY_MODE;
+       netsnmp_unix_create_path_with_mode(agentx_dir_perm);
+    }
+#endif
+
     cp1 = agentx_sockets;
     while (cp1) {
         netsnmp_transport *t;
@@ -111,44 +115,15 @@
         if (cp1 != NULL) {
             *cp1++ = '\0';
 	}
-    
-        if (sess.peername[0] == '/') {
-#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
-            /*
-             *  If this is a Unix pathname,
-             *  try and create the directory first.
-             */
-            agentx_dir_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID, 
-                                                 NETSNMP_DS_AGENT_X_DIR_PERM);
-            if (agentx_dir_perm == 0)
-                agentx_dir_perm = NETSNMP_AGENT_DIRECTORY_MODE;
-            if (mkdirhier(sess.peername, (mode_t)agentx_dir_perm, 1)) {
-                snmp_log(LOG_ERR,
-                         "Failed to create the directory for the agentX socket: %s\n",
-                         sess.peername);
-            }
-#else
-            netsnmp_sess_log_error(LOG_WARNING,
-                                   "unix domain support not available\n",
-                                   &sess);
-#endif
-        }
-    
-        /*
-         *  Otherwise, let 'snmp_open' interpret the string.
-         */
+
+       /*
+        *  Let 'snmp_open' interpret the descriptor.
+        */
         sess.local_port = AGENTX_PORT;      /* Indicate server & set default port */
         sess.remote_port = 0;
         sess.callback = handle_master_agentx_packet;
         errno = 0;
         t = netsnmp_transport_open_server("agentx", sess.peername);
-        if (t == NULL && errno == EADDRINUSE) {
-            /*
-             * Could be a left-over socket (now deleted)
-             * Try again
-             */
-            t = netsnmp_transport_open_server("agentx", sess.peername);
-        }
         if (t == NULL) {
             /*
              * diagnose snmp_open errors with the input netsnmp_session
@@ -169,41 +144,52 @@
                 netsnmp_sess_log_error(LOG_WARNING, buf, &sess);
             }
         } else {
-            session =
-                snmp_add_full(&sess, t, NULL, agentx_parse, NULL, NULL,
-                              agentx_realloc_build, agentx_check_packet, NULL);
-        }
-        if (session == NULL) {
-            netsnmp_transport_free(t);
-        }
-
 #ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
+        if (t->domain == netsnmp_UnixDomain && t->local != NULL) {
         /*
          * Apply any settings to the ownership/permissions of the AgentX socket
          */
-        agentx_sock_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
-                                              NETSNMP_DS_AGENT_X_SOCK_PERM);
-        agentx_sock_user = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
-                                              NETSNMP_DS_AGENT_X_SOCK_USER);
-        agentx_sock_group = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
-                                               NETSNMP_DS_AGENT_X_SOCK_GROUP);
-
-        if (agentx_sock_perm != 0)
-            chmod(sess.peername, agentx_sock_perm);
-        if (agentx_sock_user || agentx_sock_group) {
-            /*
-             * If either of user or group haven't been set,
-             *  then leave them unchanged.
-             */
-            if (agentx_sock_user == 0 )
-                agentx_sock_user = -1;
-            if (agentx_sock_group == 0 )
-                agentx_sock_group = -1;
-            chown(sess.peername, agentx_sock_user, agentx_sock_group);
+            int agentx_sock_perm = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+                                                  NETSNMP_DS_AGENT_X_SOCK_PERM);
+            int agentx_sock_user = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+                                                  NETSNMP_DS_AGENT_X_SOCK_USER);
+            int agentx_sock_group = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+                                                  NETSNMP_DS_AGENT_X_SOCK_GROUP);
+
+            char name[sizeof(struct sockaddr_un) + 1];
+            memcpy(name, t->local, t->local_length);
+            name[t->local_length] = '\0';
+
+            if (agentx_sock_perm != 0)
+                chmod(name, agentx_sock_perm);
+
+            if (agentx_sock_user || agentx_sock_group) {
+                /*
+                 * If either of user or group haven't been set,
+                 *  then leave them unchanged.
+                 */
+                if (agentx_sock_user == 0 )
+                    agentx_sock_user = -1;
+                if (agentx_sock_group == 0 )
+                    agentx_sock_group = -1;
+                chown(name, agentx_sock_user, agentx_sock_group);
+            }
         }
 #endif
+        session =
+            snmp_add_full(&sess, t, NULL, agentx_parse, NULL, NULL,
+                          agentx_realloc_build, agentx_check_packet, NULL);
+         }
+
+        if (session == NULL) {
+            netsnmp_transport_free(t);
+        }
     }
 
+#ifdef NETSNMP_TRANSPORT_UNIX_DOMAIN
+    netsnmp_unix_dont_create_path();
+#endif
+
     SNMP_FREE(agentx_sockets);
     DEBUGMSGTL(("agentx/master", "initializing...   DONE\n"));
 }
--- net-snmp-5.4.1/include/net-snmp/library/snmpUnixDomain.h	2006-10-27 13:19:44.000000000 -0700
+++ copy_net-snmp-5.4.1/include/net-snmp/library/snmpUnixDomain.h	2016-01-29 03:24:45.623926107 -0800
@@ -41,9 +41,20 @@
 
 void            netsnmp_unix_ctor(void);
 
+/*
+ * Support functions
+ */
+void            netsnmp_unix_create_path_with_mode(int mode);
+void            netsnmp_unix_dont_create_path(void);
+
 #ifdef __cplusplus
 }
 #endif
+#else
+
+#define netsnmp_unix_create_path_with_mode(x)
+#define netsnmp_unix_dont_create_path()
+
 #endif                          /*NETSNMP_TRANSPORT_UNIX_DOMAIN */
 
 #endif/*_SNMPUNIXDOMAIN_H*/
--- net-snmp-5.4.1/snmplib/snmpUnixDomain.c	2007-04-30 03:07:13.000000000 -0700
+++ copy_net-snmp-5.4.1/snmplib/snmpUnixDomain.c	2016-01-29 03:30:08.333575786 -0800
@@ -252,7 +252,25 @@
     }
 }
 
+static int create_path = 0;
+static mode_t create_mode;
 
+/** If trying to create unix sockets in nonexisting directories then
+ *  try to create the directory with mask mode.
+ */
+void netsnmp_unix_create_path_with_mode(int mode)
+{
+    create_path = 1;
+    create_mode = mode;
+}
+
+/** If trying to create unix sockets in nonexisting directories then
+ *  fail.
+ */
+void netsnmp_unix_dont_create_path(void)
+{
+    create_path = 0;
+}
 
 /*
  * Open a Unix-domain transport for SNMP.  Local is TRUE if addr is the local
@@ -308,7 +326,7 @@
     t->flags = NETSNMP_TRANSPORT_FLAG_STREAM;
 
     if (local) {
-      t->local = (u_char *)malloc(strlen(addr->sun_path));
+        t->local = (u_char *)malloc(strlen(addr->sun_path));
         if (t->local == NULL) {
             netsnmp_transport_free(t);
             return NULL;
@@ -325,6 +343,16 @@
 
         unlink(addr->sun_path);
         rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
+
+        if (rc != 0 && errno == ENOENT && create_path) {
+            rc = mkdirhier(addr->sun_path, create_mode, 1);
+            if (rc != 0) {
+                netsnmp_unix_close(t);
+                netsnmp_transport_free(t);
+                return NULL;
+            }
+            rc = bind(t->sock, (struct sockaddr *) addr, SUN_LEN(addr));
+        }
         if (rc != 0) {
             DEBUGMSGTL(("netsnmp_unix_transport",
                         "couldn't bind \"%s\", errno %d (%s)\n",
@@ -358,7 +386,7 @@
         }
 
     } else {
-      t->remote = (u_char *)malloc(strlen(addr->sun_path));
+        t->remote = (u_char *)malloc(strlen(addr->sun_path));
         if (t->remote == NULL) {
             netsnmp_transport_free(t);
             return NULL;
@@ -385,8 +413,8 @@
         sup->server.sun_family = AF_UNIX;
         strcpy(sup->server.sun_path, addr->sun_path);
         sup->local = 0;
-       netsnmp_sock_buffer_set(t->sock, SO_SNDBUF, local, 0);
-       netsnmp_sock_buffer_set(t->sock, SO_RCVBUF, local, 0);
+        netsnmp_sock_buffer_set(t->sock, SO_SNDBUF, local, 0);
+        netsnmp_sock_buffer_set(t->sock, SO_RCVBUF, local, 0);
     }
 
     /*