140266059SGregory Neil Shapiro /* 25dd76dd0SGregory Neil Shapiro * Copyright (c) 2001 Proofpoint, Inc. and its suppliers. 340266059SGregory Neil Shapiro * All rights reserved. 440266059SGregory Neil Shapiro * 540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set 640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of 740266059SGregory Neil Shapiro * the sendmail distribution. 840266059SGregory Neil Shapiro */ 940266059SGregory Neil Shapiro 1040266059SGregory Neil Shapiro #include <sm/gen.h> 114313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: niprop.c,v 1.9 2013-11-22 20:51:43 ca Exp $") 1240266059SGregory Neil Shapiro 1340266059SGregory Neil Shapiro #if NETINFO 1440266059SGregory Neil Shapiro #include <ctype.h> 1540266059SGregory Neil Shapiro #include <stdlib.h> 1640266059SGregory Neil Shapiro #include <sm/io.h> 1740266059SGregory Neil Shapiro #include <sm/assert.h> 1840266059SGregory Neil Shapiro #include <sm/debug.h> 1940266059SGregory Neil Shapiro #include <sm/string.h> 2040266059SGregory Neil Shapiro #include <sm/varargs.h> 2140266059SGregory Neil Shapiro #include <sm/heap.h> 2240266059SGregory Neil Shapiro 2340266059SGregory Neil Shapiro /* 2440266059SGregory Neil Shapiro ** NI_PROPVAL -- NetInfo property value lookup routine 2540266059SGregory Neil Shapiro ** 2640266059SGregory Neil Shapiro ** Parameters: 2740266059SGregory Neil Shapiro ** keydir -- the NetInfo directory name in which to search 2840266059SGregory Neil Shapiro ** for the key. 2940266059SGregory Neil Shapiro ** keyprop -- the name of the property in which to find the 3040266059SGregory Neil Shapiro ** property we are interested. Defaults to "name". 3140266059SGregory Neil Shapiro ** keyval -- the value for which we are really searching. 3240266059SGregory Neil Shapiro ** valprop -- the property name for the value in which we 3340266059SGregory Neil Shapiro ** are interested. 3440266059SGregory Neil Shapiro ** sepchar -- if non-nil, this can be multiple-valued, and 3540266059SGregory Neil Shapiro ** we should return a string separated by this 3640266059SGregory Neil Shapiro ** character. 3740266059SGregory Neil Shapiro ** 3840266059SGregory Neil Shapiro ** Returns: 3940266059SGregory Neil Shapiro ** NULL -- if: 4040266059SGregory Neil Shapiro ** 1. the directory is not found 4140266059SGregory Neil Shapiro ** 2. the property name is not found 4240266059SGregory Neil Shapiro ** 3. the property contains multiple values 4340266059SGregory Neil Shapiro ** 4. some error occurred 4440266059SGregory Neil Shapiro ** else -- the value of the lookup. 4540266059SGregory Neil Shapiro ** 4640266059SGregory Neil Shapiro ** Example: 4740266059SGregory Neil Shapiro ** To search for an alias value, use: 4840266059SGregory Neil Shapiro ** ni_propval("/aliases", "name", aliasname, "members", ',') 4940266059SGregory Neil Shapiro ** 5040266059SGregory Neil Shapiro ** Notes: 5140266059SGregory Neil Shapiro ** Caller should free the return value of ni_proval 5240266059SGregory Neil Shapiro */ 5340266059SGregory Neil Shapiro 5440266059SGregory Neil Shapiro # include <netinfo/ni.h> 5540266059SGregory Neil Shapiro 5640266059SGregory Neil Shapiro # define LOCAL_NETINFO_DOMAIN "." 5740266059SGregory Neil Shapiro # define PARENT_NETINFO_DOMAIN ".." 5840266059SGregory Neil Shapiro # define MAX_NI_LEVELS 256 5940266059SGregory Neil Shapiro 6040266059SGregory Neil Shapiro char * 6140266059SGregory Neil Shapiro ni_propval(keydir, keyprop, keyval, valprop, sepchar) 6240266059SGregory Neil Shapiro char *keydir; 6340266059SGregory Neil Shapiro char *keyprop; 6440266059SGregory Neil Shapiro char *keyval; 6540266059SGregory Neil Shapiro char *valprop; 6640266059SGregory Neil Shapiro int sepchar; 6740266059SGregory Neil Shapiro { 6840266059SGregory Neil Shapiro char *propval = NULL; 6940266059SGregory Neil Shapiro int i; 7040266059SGregory Neil Shapiro int j, alen, l; 7140266059SGregory Neil Shapiro void *ni = NULL; 7240266059SGregory Neil Shapiro void *lastni = NULL; 7340266059SGregory Neil Shapiro ni_status nis; 7440266059SGregory Neil Shapiro ni_id nid; 7540266059SGregory Neil Shapiro ni_namelist ninl; 7640266059SGregory Neil Shapiro register char *p; 7740266059SGregory Neil Shapiro char keybuf[1024]; 7840266059SGregory Neil Shapiro 7940266059SGregory Neil Shapiro /* 8040266059SGregory Neil Shapiro ** Create the full key from the two parts. 8140266059SGregory Neil Shapiro ** 8240266059SGregory Neil Shapiro ** Note that directory can end with, e.g., "name=" to specify 8340266059SGregory Neil Shapiro ** an alternate search property. 8440266059SGregory Neil Shapiro */ 8540266059SGregory Neil Shapiro 8640266059SGregory Neil Shapiro i = strlen(keydir) + strlen(keyval) + 2; 8740266059SGregory Neil Shapiro if (keyprop != NULL) 8840266059SGregory Neil Shapiro i += strlen(keyprop) + 1; 8940266059SGregory Neil Shapiro if (i >= sizeof keybuf) 9040266059SGregory Neil Shapiro return NULL; 9140266059SGregory Neil Shapiro (void) sm_strlcpyn(keybuf, sizeof keybuf, 2, keydir, "/"); 9240266059SGregory Neil Shapiro if (keyprop != NULL) 9340266059SGregory Neil Shapiro { 9440266059SGregory Neil Shapiro (void) sm_strlcat2(keybuf, keyprop, "=", sizeof keybuf); 9540266059SGregory Neil Shapiro } 9640266059SGregory Neil Shapiro (void) sm_strlcat(keybuf, keyval, sizeof keybuf); 9740266059SGregory Neil Shapiro 9840266059SGregory Neil Shapiro # if 0 9940266059SGregory Neil Shapiro if (tTd(38, 21)) 10040266059SGregory Neil Shapiro sm_dprintf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n", 10140266059SGregory Neil Shapiro keydir, keyprop, keyval, valprop, sepchar, keybuf); 102*5b0945b5SGregory Neil Shapiro # endif 10340266059SGregory Neil Shapiro 10440266059SGregory Neil Shapiro /* 10540266059SGregory Neil Shapiro ** If the passed directory and property name are found 10640266059SGregory Neil Shapiro ** in one of netinfo domains we need to search (starting 10740266059SGregory Neil Shapiro ** from the local domain moving all the way back to the 10840266059SGregory Neil Shapiro ** root domain) set propval to the property's value 10940266059SGregory Neil Shapiro ** and return it. 11040266059SGregory Neil Shapiro */ 11140266059SGregory Neil Shapiro 11240266059SGregory Neil Shapiro for (i = 0; i < MAX_NI_LEVELS && propval == NULL; i++) 11340266059SGregory Neil Shapiro { 11440266059SGregory Neil Shapiro if (i == 0) 11540266059SGregory Neil Shapiro { 11640266059SGregory Neil Shapiro nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni); 11740266059SGregory Neil Shapiro # if 0 11840266059SGregory Neil Shapiro if (tTd(38, 20)) 11940266059SGregory Neil Shapiro sm_dprintf("ni_open(LOCAL) = %d\n", nis); 120*5b0945b5SGregory Neil Shapiro # endif 12140266059SGregory Neil Shapiro } 12240266059SGregory Neil Shapiro else 12340266059SGregory Neil Shapiro { 12440266059SGregory Neil Shapiro if (lastni != NULL) 12540266059SGregory Neil Shapiro ni_free(lastni); 12640266059SGregory Neil Shapiro lastni = ni; 12740266059SGregory Neil Shapiro nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni); 12840266059SGregory Neil Shapiro # if 0 12940266059SGregory Neil Shapiro if (tTd(38, 20)) 13040266059SGregory Neil Shapiro sm_dprintf("ni_open(PARENT) = %d\n", nis); 131*5b0945b5SGregory Neil Shapiro # endif 13240266059SGregory Neil Shapiro } 13340266059SGregory Neil Shapiro 13440266059SGregory Neil Shapiro /* 13540266059SGregory Neil Shapiro ** Don't bother if we didn't get a handle on a 13640266059SGregory Neil Shapiro ** proper domain. This is not necessarily an error. 13740266059SGregory Neil Shapiro ** We would get a positive ni_status if, for instance 13840266059SGregory Neil Shapiro ** we never found the directory or property and tried 13940266059SGregory Neil Shapiro ** to open the parent of the root domain! 14040266059SGregory Neil Shapiro */ 14140266059SGregory Neil Shapiro 14240266059SGregory Neil Shapiro if (nis != 0) 14340266059SGregory Neil Shapiro break; 14440266059SGregory Neil Shapiro 14540266059SGregory Neil Shapiro /* 14640266059SGregory Neil Shapiro ** Find the path to the server information. 14740266059SGregory Neil Shapiro */ 14840266059SGregory Neil Shapiro 14940266059SGregory Neil Shapiro if (ni_pathsearch(ni, &nid, keybuf) != 0) 15040266059SGregory Neil Shapiro continue; 15140266059SGregory Neil Shapiro 15240266059SGregory Neil Shapiro /* 15340266059SGregory Neil Shapiro ** Find associated value information. 15440266059SGregory Neil Shapiro */ 15540266059SGregory Neil Shapiro 15640266059SGregory Neil Shapiro if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0) 15740266059SGregory Neil Shapiro continue; 15840266059SGregory Neil Shapiro 15940266059SGregory Neil Shapiro # if 0 16040266059SGregory Neil Shapiro if (tTd(38, 20)) 16140266059SGregory Neil Shapiro sm_dprintf("ni_lookupprop: len=%d\n", 16240266059SGregory Neil Shapiro ninl.ni_namelist_len); 163*5b0945b5SGregory Neil Shapiro # endif 16440266059SGregory Neil Shapiro 16540266059SGregory Neil Shapiro /* 16640266059SGregory Neil Shapiro ** See if we have an acceptable number of values. 16740266059SGregory Neil Shapiro */ 16840266059SGregory Neil Shapiro 16940266059SGregory Neil Shapiro if (ninl.ni_namelist_len <= 0) 17040266059SGregory Neil Shapiro continue; 17140266059SGregory Neil Shapiro 17240266059SGregory Neil Shapiro if (sepchar == '\0' && ninl.ni_namelist_len > 1) 17340266059SGregory Neil Shapiro { 17440266059SGregory Neil Shapiro ni_namelist_free(&ninl); 17540266059SGregory Neil Shapiro continue; 17640266059SGregory Neil Shapiro } 17740266059SGregory Neil Shapiro 17840266059SGregory Neil Shapiro /* 17940266059SGregory Neil Shapiro ** Calculate number of bytes needed and build result 18040266059SGregory Neil Shapiro */ 18140266059SGregory Neil Shapiro 18240266059SGregory Neil Shapiro alen = 1; 18340266059SGregory Neil Shapiro for (j = 0; j < ninl.ni_namelist_len; j++) 18440266059SGregory Neil Shapiro alen += strlen(ninl.ni_namelist_val[j]) + 1; 18540266059SGregory Neil Shapiro propval = p = sm_malloc(alen); 18640266059SGregory Neil Shapiro if (propval == NULL) 18740266059SGregory Neil Shapiro goto cleanup; 18840266059SGregory Neil Shapiro for (j = 0; j < ninl.ni_namelist_len; j++) 18940266059SGregory Neil Shapiro { 19040266059SGregory Neil Shapiro (void) sm_strlcpy(p, ninl.ni_namelist_val[j], alen); 19140266059SGregory Neil Shapiro l = strlen(p); 19240266059SGregory Neil Shapiro p += l; 19340266059SGregory Neil Shapiro *p++ = sepchar; 19440266059SGregory Neil Shapiro alen -= l + 1; 19540266059SGregory Neil Shapiro } 19640266059SGregory Neil Shapiro *--p = '\0'; 19740266059SGregory Neil Shapiro 19840266059SGregory Neil Shapiro ni_namelist_free(&ninl); 19940266059SGregory Neil Shapiro } 20040266059SGregory Neil Shapiro 20140266059SGregory Neil Shapiro cleanup: 20240266059SGregory Neil Shapiro if (ni != NULL) 20340266059SGregory Neil Shapiro ni_free(ni); 20440266059SGregory Neil Shapiro if (lastni != NULL && ni != lastni) 20540266059SGregory Neil Shapiro ni_free(lastni); 20640266059SGregory Neil Shapiro # if 0 20740266059SGregory Neil Shapiro if (tTd(38, 20)) 20840266059SGregory Neil Shapiro sm_dprintf("ni_propval returns: '%s'\n", propval); 209*5b0945b5SGregory Neil Shapiro # endif 21040266059SGregory Neil Shapiro 21140266059SGregory Neil Shapiro return propval; 21240266059SGregory Neil Shapiro } 21340266059SGregory Neil Shapiro #endif /* NETINFO */ 214