2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A * This library contains a set of routines that are shared amongst inetd, 2N/A * inetadm, inetconv and the formerly internal inetd services. Amongst the 2N/A * routines are ones for reading and validating the configuration of an 2N/A * inetd service, a routine for requesting inetd be refreshed, ones for 2N/A * reading, calculating and writing the hash of an inetd.conf file, and 2N/A * numerous utility routines shared amongst the formerly internal inetd 2N/A * Inactivity timer used by dg_template(). After this many seconds of network 2N/A * inactivity dg_template will cease listening for new datagrams and return. 2N/A * Return a reference to the property table. Number of entries in table 2N/A * are returned in num_elements argument. 2N/A * find_prop takes an array of inetd_prop_t's, the name of an inetd 2N/A * property, the type expected, and returns a pointer to the matching member, 2N/A * get_prop_value_int takes an array of inetd_prop_t's together with the name of 2N/A * an inetd property and returns the value of the property. It's expected that 2N/A * the property exists in the searched array. 2N/A * get_prop_value_count takes an array of inetd_prop_t's together with the name 2N/A * of an inetd property and returns the value of the property. It's expected 2N/A * that the property exists in the searched array. 2N/A * get_prop_value_boolean takes an array of inetd_prop_t's together with the 2N/A * name of an inetd property and returns the value of the property. It's 2N/A * expected that the property exists in the searched array. 2N/A * get_prop_value_string takes an array of inetd_prop_t's together with 2N/A * the name of an inetd property and returns the value of the property. 2N/A * It's expected that the property exists in the searched array. 2N/A * get_prop_value_string_list takes an array of inetd_prop_t's together 2N/A * with the name of an inetd property and returns the value of the property. 2N/A * It's expected that the property exists in the searched array. 2N/A * put_prop_value_int takes an array of inetd_prop_t's, a name of an inetd 2N/A * property, and a value. It copies the value into the property 2N/A * in the array. It's expected that the property exists in the searched array. 2N/A * put_prop_value_count takes an array of inetd_prop_t's, a name of an inetd 2N/A * property, and a value. It copies the value into the property 2N/A * in the array. It's expected that the property exists in the searched array. 2N/A * put_prop_value_boolean takes an array of inetd_prop_t's, a name of an inetd 2N/A * property, and a value. It copies the value into the property 2N/A * in the array. It's expected that the property exists in the searched array. 2N/A * put_prop_value_string takes an array of inetd_prop_t's, a name of an inetd 2N/A * property, and a value. It duplicates the value into the property 2N/A * in the array, and returns B_TRUE for success and B_FALSE for failure. It's 2N/A * expected that the property exists in the searched array. 2N/A * put_prop_value_string_list takes an array of inetd_prop_t's, a name of an 2N/A * inetd property, and a value. It copies the value into the property 2N/A * in the array. It's expected that the property exists in the searched array. 2N/A * If 'proto' is a valid netid, and no memory allocations fail, returns a 2N/A * pointer to an allocated and initialized rpc_info_t, else NULL. 2N/A * Determine whether this is a loopback transport. If getnetconfigent() 2N/A * fails, we check to see whether it was the result of a v6 proto 2N/A * being specified and no IPv6 interface was configured on the system; 2N/A * if this holds, we know it must not be a loopback transport, else 2N/A * getnetconfigent() must be miss-behaving, so return an error. 2N/A /* free up conn ind queue */ 2N/A * Allocate, initialize and return a pointer to a tlx_info_t structure. 2N/A * On memory allocation failure NULL is returned. 2N/A /* store device name, constructing if necessary */ 2N/A * Returns B_TRUE if this is a v6 protocol valid for both TLI and socket 2N/A * based services, else B_FALSE. 2N/A * Returns B_TRUE if this is a valid v6 protocol for a socket based service, 2N/A * Free all the memory consumed by 'pi' associated with the instance 2N/A * with configuration 'cfg'. 2N/A * Overwrite the socket address with the address specified by the 2N/A * bind_addr property. 2N/A * valid_props validates all the properties in an array of inetd_prop_t's, 2N/A * marking each property as valid or invalid. If any properties are invalid, 2N/A * it returns B_FALSE, otherwise it returns B_TRUE. Note that some properties 2N/A * are interdependent, so if one is invalid, it leaves others in an 2N/A * indeterminate state (such as ISRPC and SVC_NAME). In this case, the 2N/A * indeterminate property will be marked valid. IE, the only properties 2N/A * marked invalid are those that are KNOWN to be invalid. 2N/A * Piggy-backed onto this validation if 'fmri' is non-NULL is the construction 2N/A * of a structured configuration, a basic_cfg_t, which is used by inetd. 2N/A * If 'fmri' is set then the latter three parameters need to be set to 2N/A * non-NULL values, and if the configuration is valid, the storage referenced 2N/A * by cfgpp is set to point at an initialized basic_cfg_t. 2N/A * Set all checkable properties to valid as a baseline. We'll be 2N/A * marking all invalid properties. 2N/A /* Check a service name was supplied */ 2N/A /* Check that iswait and isrpc have valid boolean values */ 2N/A * This is an RPC service, so ensure that the RPC version 2N/A * numbers are zero or greater, that the low version isn't 2N/A * greater than the high version and a valid program name 2N/A /* Check that the socket type is one of the acceptable values. */ 2N/A /* Get the bind address */ 2N/A * proto property and check that they're valid and perform checks on 2N/A * other fields that are tied-in with the proto. 2N/A * If we don't know whether it's an rpc service or its 2N/A * endpoint type, we can't do any of the proto checks as we 2N/A * have no context; break out. 2N/A /* skip proto specific processing if the proto isn't set. */ 2N/A * This is a TLI/RPC service, so get the next netid, expanding 2N/A * any supplied nettype. 2N/A * Either this is the first time around or 2N/A * we've exhausted the last set of netids, so 2N/A * try and get the next set using the currently 2N/A * indexed proto entry. 2N/A /* strip a trailing only to simplify further processing */ 2N/A * Check if we've got a valid netid. If 2N/A * getnetconfigent() fails, we check to see whether 2N/A * we've got a v6 netid that may have been rejected 2N/A * because no IPv6 interface was configured before 2N/A * flagging 'proto' as invalid. If the latter condition 2N/A * holds, we don't flag the proto as invalid, and 2N/A * leave inetd to handle the value appropriately 2N/A * when it tries to listen on behalf of the service. 2N/A * dissallow datagram type nowait services 2N/A * We're running in validate only mode. Don't bother creating 2N/A * any proto structures (they don't do any further validation). 2N/A * Create the apropriate transport info structure. 2N/A /* already in network order */ 2N/A * Store the supplied proto string for error reporting, 2N/A * re-attaching the 'only' suffix if one was taken off. 2N/A /* validate non-RPC service name */ 2N/A * Make getservbyname_r do its lookup without a 2N/A * Since getservbyname & getprotobyname don't 2N/A * support tcp6, udp6 or sctp6 take off the 6 2N/A * digit from protocol. 2N/A /* add new proto entry to proto_list */ 2N/A * Check that the exec string for the start method actually exists and 2N/A * that the user is either a valid username or uid. Note we don't 2N/A * mandate the setting of these fields, and don't do any checks 2N/A * for arg0, hence its absence. 2N/A /* Don't pass any arguments to access() */ 2N/A * Iterate through the properties in the array verifying that any 2N/A * default properties are valid, and setting the return boolean 2N/A * according to whether any properties were marked invalid. 2N/A /* pass back the basic_cfg_t if requested and it's a valid config */ 2N/A * validate_default_prop takes the name of an inetd property, and a value 2N/A * for that property. It returns B_TRUE if the property is valid, and B_FALSE 2N/A * if the proposed value isn't valid for that property. 2N/A (j +
2) *
sizeof (
char *))) ==
NULL) {
2N/A * read_props reads either the full set of properties for instance 'instance' 2N/A * (including defaults - pulling them in from inetd where necessary) if 2N/A * 'instance' is non-null, else just the defaults from inetd. The properties 2N/A * are returned in an allocated inetd_prop_t array, which must be freed 2N/A * using free_instance_props(). If an error occurs NULL is returned and 'err' 2N/A * is set to indicate the cause, else a pointer to the read properties is 2N/A * In non-default-only mode where we're reading a 2N/A * default property, since the property wasn't 2N/A * found in the instance, try and read inetd's default 2N/A * Read all properties applicable to 'instance' (including defaults). 2N/A * Read the default properties from inetd's defaults property group. 2N/A * refresh_inetd requests that inetd re-read all of the information that it's 2N/A * Returns the id of the socket type 'type_str' that can be used in a call 2N/A * to socket(). If an unknown type string is passed returns -1, else the id. 2N/A * Takes either an RPC service name or number in string form as 'svc_name', and 2N/A * returns an integer format program number for the service. If the name isn't 2N/A * recognized as a valid RPC service name or isn't a valid number, -1 is 2N/A * returned, else the services program number. 2N/A * calculate_hash calculates the MD5 message-digest of the file pathname. 2N/A * On success, hash is modified to point to the digest string and 0 is returned. 2N/A * Otherwise, -1 is returned and errno is set to indicate the error. 2N/A * The space for the digest string is obtained using malloc(3C) and should be 2N/A * freed by the caller. 2N/A /* allocate space for a 16-byte MD5 digest as a string of hex digits */ 2N/A * retrieve_inetd_hash retrieves inetd's configuration file hash from the 2N/A * repository. On success, hash is modified to point to the hash string and 2N/A * SCF_ERROR_NONE is returned. Otherwise, the scf_error value is returned. 2N/A * The space for the hash string is obtained using malloc(3C) and should be 2N/A * freed by the caller. 2N/A * store_inetd_hash stores the string hash in inetd's configuration file hash 2N/A * in the repository. On success, SCF_ERROR_NONE is returned. Otherwise, the 2N/A * scf_error value is returned. 2N/A * This is a wrapper function for inet_ntop(). In case the af is AF_INET6 2N/A * and the address pointed by src is a IPv4-mapped IPv6 address, it returns 2N/A * a printable IPv4 address, not an IPv4-mapped IPv6 address. In other cases it 2N/A * behaves just like inet_ntop(). 2N/A * inetd specific setproctitle. It sets the title so that it contains 2N/A * 'svc_name' followed by, if obtainable, the address of the remote end of 2N/A * NOTE: The argv manipulation in this function should be replaced when a 2N/A * common version of setproctitle is made available. 2N/A /* we set argv[0] to point at our static storage. */ 2N/A * This function is a datagram service template. It acts as a datagram wait 2N/A * type server, waiting for datagrams to come in, and when they do passing 2N/A * their contents, as-well as the socket they came in on and the remote 2N/A * address, in a call to the callback function 'cb'. If no datagrams are 2N/A * received for DG_INACTIVITY_TIMEOUT seconds the function exits with code 0. 2N/A /* denial-of-service attack possibility - ignore it */ 2N/A "Incoming datagram from internal inetd service received; ignoring.");
2N/A * An extension of write() or sendto() that keeps trying until either the full 2N/A * request has completed or a non-EINTR error occurs. If 'to' is set to a 2N/A * non-NULL value, sendto() is extended, else write(). Returns 0 on success 2N/A * Free up the memory occupied by string array 'strs'. 2N/A * Parse the proto list string into an allocated array of proto strings, 2N/A * returning a pointer to this array. If one of the protos is too big 2N/A * errno is set to E2BIG and NULL is returned; if memory allocation failure 2N/A * occurs errno is set to ENOMEM and NULL is returned; else on success 2N/A * a pointer the string array is returned. 2N/A /* copy the parameter as strtok modifies its parameters */ 2N/A * Returns an allocated string array of netids corresponding with 'proto'. The 2N/A * function first tries to interpret 'proto' as a nettype to get its netids. 2N/A * If this fails it tries to interpret it as a netid. If 'proto' is neither 2N/A * a nettype or a netid or a memory allocation failures occurs NULL is 2N/A * returned, else a pointer to an array of netids associated with 'proto' is 2N/A /* expand nettype */ 2N/A (i +
2) *
sizeof (
char *))) ==
NULL)