16ba597c5SAnurag S. Maskey /*
26ba597c5SAnurag S. Maskey  * CDDL HEADER START
36ba597c5SAnurag S. Maskey  *
46ba597c5SAnurag S. Maskey  * The contents of this file are subject to the terms of the
56ba597c5SAnurag S. Maskey  * Common Development and Distribution License (the "License").
66ba597c5SAnurag S. Maskey  * You may not use this file except in compliance with the License.
76ba597c5SAnurag S. Maskey  *
86ba597c5SAnurag S. Maskey  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96ba597c5SAnurag S. Maskey  * or http://www.opensolaris.org/os/licensing.
106ba597c5SAnurag S. Maskey  * See the License for the specific language governing permissions
116ba597c5SAnurag S. Maskey  * and limitations under the License.
126ba597c5SAnurag S. Maskey  *
136ba597c5SAnurag S. Maskey  * When distributing Covered Code, include this CDDL HEADER in each
146ba597c5SAnurag S. Maskey  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156ba597c5SAnurag S. Maskey  * If applicable, add the following below this CDDL HEADER, with the
166ba597c5SAnurag S. Maskey  * fields enclosed by brackets "[]" replaced with your own identifying
176ba597c5SAnurag S. Maskey  * information: Portions Copyright [yyyy] [name of copyright owner]
186ba597c5SAnurag S. Maskey  *
196ba597c5SAnurag S. Maskey  * CDDL HEADER END
206ba597c5SAnurag S. Maskey  */
216ba597c5SAnurag S. Maskey 
226ba597c5SAnurag S. Maskey /*
236ba597c5SAnurag S. Maskey  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
246ba597c5SAnurag S. Maskey  * Use is subject to license terms.
256ba597c5SAnurag S. Maskey  */
266ba597c5SAnurag S. Maskey 
276ba597c5SAnurag S. Maskey #include <assert.h>
286ba597c5SAnurag S. Maskey #include <stdlib.h>
296ba597c5SAnurag S. Maskey #include <strings.h>
306ba597c5SAnurag S. Maskey #include <string.h>
316ba597c5SAnurag S. Maskey 
326ba597c5SAnurag S. Maskey #include "libnwam_impl.h"
336ba597c5SAnurag S. Maskey #include <libintl.h>
346ba597c5SAnurag S. Maskey #include <libnwam.h>
356ba597c5SAnurag S. Maskey 
366ba597c5SAnurag S. Maskey /*
376ba597c5SAnurag S. Maskey  * Generic object manipulation functions. Given an object handle and
386ba597c5SAnurag S. Maskey  * other parameters, create/destroy objects, walk them, walk their
396ba597c5SAnurag S. Maskey  * properties, modify/retrieve/delete properties, enable/disable them,
406ba597c5SAnurag S. Maskey  * etc. All object handles are "struct nwam_handle *" objects, sharing
416ba597c5SAnurag S. Maskey  * the same description based on the object type, name, original name
426ba597c5SAnurag S. Maskey  * (used in renaming) and associated data representing properties.
436ba597c5SAnurag S. Maskey  */
446ba597c5SAnurag S. Maskey 
456ba597c5SAnurag S. Maskey nwam_error_t
nwam_handle_create(nwam_object_type_t type,const char * name,struct nwam_handle ** hpp)466ba597c5SAnurag S. Maskey nwam_handle_create(nwam_object_type_t type, const char *name,
476ba597c5SAnurag S. Maskey     struct nwam_handle **hpp)
486ba597c5SAnurag S. Maskey {
496ba597c5SAnurag S. Maskey 
506ba597c5SAnurag S. Maskey 	assert(name != NULL && hpp != NULL);
516ba597c5SAnurag S. Maskey 
526ba597c5SAnurag S. Maskey 	if (strnlen(name, NWAM_MAX_NAME_LEN) > NWAM_MAX_NAME_LEN) {
536ba597c5SAnurag S. Maskey 		*hpp = NULL;
546ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
556ba597c5SAnurag S. Maskey 	}
566ba597c5SAnurag S. Maskey 
576ba597c5SAnurag S. Maskey 	if ((*hpp = calloc(1, sizeof (struct nwam_handle))) == NULL)
586ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
596ba597c5SAnurag S. Maskey 
606ba597c5SAnurag S. Maskey 	(*hpp)->nwh_object_type = type;
616ba597c5SAnurag S. Maskey 	(void) strlcpy((*hpp)->nwh_name, name, strlen(name) + 1);
626ba597c5SAnurag S. Maskey 	(*hpp)->nwh_committed = B_FALSE;
636ba597c5SAnurag S. Maskey 	(*hpp)->nwh_data = NULL;
646ba597c5SAnurag S. Maskey 
656ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
666ba597c5SAnurag S. Maskey }
676ba597c5SAnurag S. Maskey 
686ba597c5SAnurag S. Maskey /*
696ba597c5SAnurag S. Maskey  * Read object of specified type from dbname.
706ba597c5SAnurag S. Maskey  */
716ba597c5SAnurag S. Maskey nwam_error_t
nwam_read(nwam_object_type_t type,const char * dbname,const char * name,uint64_t flags,struct nwam_handle ** hpp)726ba597c5SAnurag S. Maskey nwam_read(nwam_object_type_t type, const char *dbname, const char *name,
736ba597c5SAnurag S. Maskey     uint64_t flags, struct nwam_handle **hpp)
746ba597c5SAnurag S. Maskey {
756ba597c5SAnurag S. Maskey 	nwam_error_t err;
766ba597c5SAnurag S. Maskey 	char dbname_copy[MAXPATHLEN];
776ba597c5SAnurag S. Maskey 
786ba597c5SAnurag S. Maskey 	assert(name != NULL && hpp != NULL);
796ba597c5SAnurag S. Maskey 
806ba597c5SAnurag S. Maskey 	if (dbname != NULL)
816ba597c5SAnurag S. Maskey 		(void) strlcpy(dbname_copy, dbname, sizeof (dbname_copy));
826ba597c5SAnurag S. Maskey 
836ba597c5SAnurag S. Maskey 	if ((err = nwam_valid_flags(flags, NWAM_FLAG_BLOCKING)) != NWAM_SUCCESS)
846ba597c5SAnurag S. Maskey 		return (err);
856ba597c5SAnurag S. Maskey 	if ((err = nwam_handle_create(type, name, hpp)) != NWAM_SUCCESS)
866ba597c5SAnurag S. Maskey 		return (err);
876ba597c5SAnurag S. Maskey 
886ba597c5SAnurag S. Maskey 	if ((err = nwam_read_object_from_backend
896ba597c5SAnurag S. Maskey 	    (dbname != NULL ? dbname_copy : NULL,
906ba597c5SAnurag S. Maskey 	    type == NWAM_OBJECT_TYPE_NCP ? NULL : (*hpp)->nwh_name, flags,
916ba597c5SAnurag S. Maskey 	    &(*hpp)->nwh_data)) != NWAM_SUCCESS) {
926ba597c5SAnurag S. Maskey 		free(*hpp);
936ba597c5SAnurag S. Maskey 		*hpp = NULL;
946ba597c5SAnurag S. Maskey 		return (err);
956ba597c5SAnurag S. Maskey 	}
966ba597c5SAnurag S. Maskey 	if (type == NWAM_OBJECT_TYPE_NCP && dbname != NULL) {
976ba597c5SAnurag S. Maskey 		char *ncpname;
986ba597c5SAnurag S. Maskey 
996ba597c5SAnurag S. Maskey 		/*
1006ba597c5SAnurag S. Maskey 		 * dbname_copy may have been changed due to case-insensitive
1016ba597c5SAnurag S. Maskey 		 * match against the actual NCP configuration file.
1026ba597c5SAnurag S. Maskey 		 */
1036ba597c5SAnurag S. Maskey 		if (nwam_ncp_file_to_name(dbname_copy, &ncpname)
1046ba597c5SAnurag S. Maskey 		    == NWAM_SUCCESS) {
1056ba597c5SAnurag S. Maskey 			(void) strlcpy((*hpp)->nwh_name, ncpname,
1066ba597c5SAnurag S. Maskey 			    sizeof ((*hpp)->nwh_name));
1076ba597c5SAnurag S. Maskey 			free(ncpname);
1086ba597c5SAnurag S. Maskey 		}
1096ba597c5SAnurag S. Maskey 	}
1106ba597c5SAnurag S. Maskey 
1116ba597c5SAnurag S. Maskey 	(*hpp)->nwh_committed = B_TRUE;
1126ba597c5SAnurag S. Maskey 
1136ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1146ba597c5SAnurag S. Maskey }
1156ba597c5SAnurag S. Maskey 
1166ba597c5SAnurag S. Maskey /*
1176ba597c5SAnurag S. Maskey  * Create simply creates the handle - the object-specific function must
1186ba597c5SAnurag S. Maskey  * then fill in property values.
1196ba597c5SAnurag S. Maskey  */
1206ba597c5SAnurag S. Maskey nwam_error_t
nwam_create(nwam_object_type_t type,const char * dbname,const char * name,struct nwam_handle ** hpp)1216ba597c5SAnurag S. Maskey nwam_create(nwam_object_type_t type, const char *dbname, const char *name,
1226ba597c5SAnurag S. Maskey     struct nwam_handle **hpp)
1236ba597c5SAnurag S. Maskey {
1246ba597c5SAnurag S. Maskey 	struct nwam_handle *hp;
1256ba597c5SAnurag S. Maskey 
1266ba597c5SAnurag S. Maskey 	assert(hpp != NULL && name != NULL);
1276ba597c5SAnurag S. Maskey 
1286ba597c5SAnurag S. Maskey 	if (nwam_read(type, dbname, name, 0, &hp) == NWAM_SUCCESS) {
1296ba597c5SAnurag S. Maskey 		nwam_free(hp);
1306ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_EXISTS);
1316ba597c5SAnurag S. Maskey 	}
1326ba597c5SAnurag S. Maskey 	/* Create handle */
1336ba597c5SAnurag S. Maskey 	return (nwam_handle_create(type, name, hpp));
1346ba597c5SAnurag S. Maskey }
1356ba597c5SAnurag S. Maskey 
1366ba597c5SAnurag S. Maskey nwam_error_t
nwam_get_name(struct nwam_handle * hp,char ** namep)1376ba597c5SAnurag S. Maskey nwam_get_name(struct nwam_handle *hp, char **namep)
1386ba597c5SAnurag S. Maskey {
1396ba597c5SAnurag S. Maskey 	assert(hp != NULL && namep != NULL);
1406ba597c5SAnurag S. Maskey 
1416ba597c5SAnurag S. Maskey 	if ((*namep = strdup(hp->nwh_name)) == NULL) {
1426ba597c5SAnurag S. Maskey 		*namep = NULL;
1436ba597c5SAnurag S. Maskey 		return (NWAM_NO_MEMORY);
1446ba597c5SAnurag S. Maskey 	}
1456ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1466ba597c5SAnurag S. Maskey }
1476ba597c5SAnurag S. Maskey 
1486ba597c5SAnurag S. Maskey nwam_error_t
nwam_set_name(struct nwam_handle * hp,const char * name)1496ba597c5SAnurag S. Maskey nwam_set_name(struct nwam_handle *hp, const char *name)
1506ba597c5SAnurag S. Maskey {
1516ba597c5SAnurag S. Maskey 	assert(hp != NULL && name != NULL);
1526ba597c5SAnurag S. Maskey 
1536ba597c5SAnurag S. Maskey 	if (hp->nwh_committed)
1546ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_READ_ONLY);
1556ba597c5SAnurag S. Maskey 
1566ba597c5SAnurag S. Maskey 	if (strlen(name) >= sizeof (hp->nwh_name))
1576ba597c5SAnurag S. Maskey 		return (NWAM_INVALID_ARG);
1586ba597c5SAnurag S. Maskey 
1596ba597c5SAnurag S. Maskey 	(void) strcpy(hp->nwh_name, name);
1606ba597c5SAnurag S. Maskey 
1616ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
1626ba597c5SAnurag S. Maskey }
1636ba597c5SAnurag S. Maskey 
1646ba597c5SAnurag S. Maskey /* Compare object names c1 and c2 using strcasecmp() */
1656ba597c5SAnurag S. Maskey static int
name_cmp(const void * c1,const void * c2)1666ba597c5SAnurag S. Maskey name_cmp(const void *c1, const void *c2)
1676ba597c5SAnurag S. Maskey {
1686ba597c5SAnurag S. Maskey 	nwam_ncu_type_t t1, t2;
1696ba597c5SAnurag S. Maskey 	char		*n1, *n2;
1706ba597c5SAnurag S. Maskey 
1716ba597c5SAnurag S. Maskey 	/* If c1 and c2 are typed NCU names, compare names without the types */
1726ba597c5SAnurag S. Maskey 	if (nwam_ncu_typed_name_to_name(*(const char **)c1, &t1, &n1)
1736ba597c5SAnurag S. Maskey 	    == NWAM_SUCCESS &&
1746ba597c5SAnurag S. Maskey 	    nwam_ncu_typed_name_to_name(*(const char **)c2, &t2, &n2)
1756ba597c5SAnurag S. Maskey 	    == NWAM_SUCCESS) {
1766ba597c5SAnurag S. Maskey 		int ret = strcasecmp(n1, n2);
1776ba597c5SAnurag S. Maskey 		free(n1);
1786ba597c5SAnurag S. Maskey 		free(n2);
1796ba597c5SAnurag S. Maskey 
1806ba597c5SAnurag S. Maskey 		/* For NCUs with the same name, compare their types */
1816ba597c5SAnurag S. Maskey 		if (ret == 0) {
1826ba597c5SAnurag S. Maskey 			if (t1 < t2)
1836ba597c5SAnurag S. Maskey 				ret = -1;
1846ba597c5SAnurag S. Maskey 			else if (t1 > t2)
1856ba597c5SAnurag S. Maskey 				ret = 1;
1866ba597c5SAnurag S. Maskey 		}
1876ba597c5SAnurag S. Maskey 		return (ret);
1886ba597c5SAnurag S. Maskey 	}
1896ba597c5SAnurag S. Maskey 
1906ba597c5SAnurag S. Maskey 	return (strcasecmp(*(const char **)c1, *(const char **)c2));
1916ba597c5SAnurag S. Maskey }
1926ba597c5SAnurag S. Maskey 
1936ba597c5SAnurag S. Maskey /*
1946ba597c5SAnurag S. Maskey  * Generic walk function takes the standard walk arguments, and in addition
1956ba597c5SAnurag S. Maskey  * takes a selection callback that is object-specific. If this returns
1966ba597c5SAnurag S. Maskey  * 0, the object is a valid selection for the walk and the callback is called.
1976ba597c5SAnurag S. Maskey  * Otherwise, it is skipped.
1986ba597c5SAnurag S. Maskey  */
1996ba597c5SAnurag S. Maskey nwam_error_t
nwam_walk(nwam_object_type_t type,const char * dbname,int (* cb)(struct nwam_handle *,void *),void * data,uint64_t flags,int * retp,int (* selectcb)(struct nwam_handle *,uint64_t,void *))2006ba597c5SAnurag S. Maskey nwam_walk(nwam_object_type_t type, const char *dbname,
2016ba597c5SAnurag S. Maskey     int(*cb)(struct nwam_handle *, void *),
2026ba597c5SAnurag S. Maskey     void *data, uint64_t flags, int *retp,
2036ba597c5SAnurag S. Maskey     int(*selectcb)(struct nwam_handle *, uint64_t, void *))
2046ba597c5SAnurag S. Maskey {
2056ba597c5SAnurag S. Maskey 	void *objlist;
2066ba597c5SAnurag S. Maskey 	nwam_value_t value;
2076ba597c5SAnurag S. Maskey 	char **object_names;
2086ba597c5SAnurag S. Maskey 	uint_t i, num_objects = 0;
2096ba597c5SAnurag S. Maskey 	struct nwam_handle *hp;
2106ba597c5SAnurag S. Maskey 	nwam_error_t err;
2116ba597c5SAnurag S. Maskey 	int ret = 0;
2126ba597c5SAnurag S. Maskey 
2136ba597c5SAnurag S. Maskey 	assert(cb != NULL);
2146ba597c5SAnurag S. Maskey 
2156ba597c5SAnurag S. Maskey 	/*
2166ba597c5SAnurag S. Maskey 	 * To walk a set of objects, call nwam_read_object_from_backend()
2176ba597c5SAnurag S. Maskey 	 * with a "dbname" argument set to the container db name and
2186ba597c5SAnurag S. Maskey 	 * the object name set to NULL. This returns an nvlist with one
2196ba597c5SAnurag S. Maskey 	 * member - the NWAM_OBJECT_NAMES_STRING - and the values it contains
2206ba597c5SAnurag S. Maskey 	 * represent the names of the objects.  Read each in turn, calling
2216ba597c5SAnurag S. Maskey 	 * the callback function.
2226ba597c5SAnurag S. Maskey 	 */
2236ba597c5SAnurag S. Maskey 	if ((err = nwam_read_object_from_backend((char *)dbname, NULL, flags,
2246ba597c5SAnurag S. Maskey 	    &objlist)) != NWAM_SUCCESS) {
2256ba597c5SAnurag S. Maskey 		if (err == NWAM_ENTITY_NOT_FOUND) {
2266ba597c5SAnurag S. Maskey 			/*
2276ba597c5SAnurag S. Maskey 			 * This indicates the dbname container is not present.
2286ba597c5SAnurag S. Maskey 			 * Do not pass back an error in this case, since it is
2296ba597c5SAnurag S. Maskey 			 * valid for a container not to exist.
2306ba597c5SAnurag S. Maskey 			 */
2316ba597c5SAnurag S. Maskey 			return (NWAM_SUCCESS);
2326ba597c5SAnurag S. Maskey 		}
2336ba597c5SAnurag S. Maskey 		return (err);
2346ba597c5SAnurag S. Maskey 	}
2356ba597c5SAnurag S. Maskey 
2366ba597c5SAnurag S. Maskey 	if ((err = nwam_get_prop_value(objlist, NWAM_OBJECT_NAMES_STRING,
2376ba597c5SAnurag S. Maskey 	    &value)) != NWAM_SUCCESS) {
2386ba597c5SAnurag S. Maskey 		nwam_free_object_list(objlist);
2396ba597c5SAnurag S. Maskey 		return (err);
2406ba597c5SAnurag S. Maskey 	}
2416ba597c5SAnurag S. Maskey 	err = nwam_value_get_string_array(value, &object_names, &num_objects);
2426ba597c5SAnurag S. Maskey 	nwam_free_object_list(objlist);
2436ba597c5SAnurag S. Maskey 	if (err != NWAM_SUCCESS) {
2446ba597c5SAnurag S. Maskey 		nwam_value_free(value);
2456ba597c5SAnurag S. Maskey 		return (err);
2466ba597c5SAnurag S. Maskey 	}
2476ba597c5SAnurag S. Maskey 
2486ba597c5SAnurag S. Maskey 	/* sort the object names alphabetically */
2496ba597c5SAnurag S. Maskey 	qsort(object_names, num_objects, sizeof (char *), name_cmp);
2506ba597c5SAnurag S. Maskey 
2516ba597c5SAnurag S. Maskey 	for (i = 0; i < num_objects; i++) {
2526ba597c5SAnurag S. Maskey 		err = nwam_read(type, dbname, object_names[i],
2536ba597c5SAnurag S. Maskey 		    flags & NWAM_FLAG_GLOBAL_MASK, &hp);
2546ba597c5SAnurag S. Maskey 		/* An object may have disappeared.  If so, skip it. */
2556ba597c5SAnurag S. Maskey 		if (err == NWAM_ENTITY_NOT_FOUND)
2566ba597c5SAnurag S. Maskey 			continue;
2576ba597c5SAnurag S. Maskey 		if (err != NWAM_SUCCESS) {
2586ba597c5SAnurag S. Maskey 			nwam_value_free(value);
2596ba597c5SAnurag S. Maskey 			return (err);
2606ba597c5SAnurag S. Maskey 		}
2616ba597c5SAnurag S. Maskey 		if ((selectcb == NULL) || (selectcb(hp, flags, data) == 0)) {
2626ba597c5SAnurag S. Maskey 			ret = cb(hp, data);
2636ba597c5SAnurag S. Maskey 			if (ret != 0) {
2646ba597c5SAnurag S. Maskey 				nwam_free(hp);
2656ba597c5SAnurag S. Maskey 				nwam_value_free(value);
2666ba597c5SAnurag S. Maskey 				if (retp != NULL)
2676ba597c5SAnurag S. Maskey 					*retp = ret;
2686ba597c5SAnurag S. Maskey 				return (NWAM_WALK_HALTED);
2696ba597c5SAnurag S. Maskey 			}
2706ba597c5SAnurag S. Maskey 		}
2716ba597c5SAnurag S. Maskey 		nwam_free(hp);
2726ba597c5SAnurag S. Maskey 	}
2736ba597c5SAnurag S. Maskey 	nwam_value_free(value);
2746ba597c5SAnurag S. Maskey 
2756ba597c5SAnurag S. Maskey 	if (retp != NULL)
2766ba597c5SAnurag S. Maskey 		*retp = ret;
2776ba597c5SAnurag S. Maskey 	return (err);
2786ba597c5SAnurag S. Maskey }
2796ba597c5SAnurag S. Maskey 
2806ba597c5SAnurag S. Maskey void
nwam_free(struct nwam_handle * hp)2816ba597c5SAnurag S. Maskey nwam_free(struct nwam_handle *hp)
2826ba597c5SAnurag S. Maskey {
2836ba597c5SAnurag S. Maskey 	if (hp != NULL) {
2846ba597c5SAnurag S. Maskey 		if (hp->nwh_data != NULL)
2856ba597c5SAnurag S. Maskey 			nwam_free_object_list(hp->nwh_data);
2866ba597c5SAnurag S. Maskey 		free(hp);
2876ba597c5SAnurag S. Maskey 	}
2886ba597c5SAnurag S. Maskey }
2896ba597c5SAnurag S. Maskey 
2906ba597c5SAnurag S. Maskey /*
2916ba597c5SAnurag S. Maskey  * Copy object represented by oldhp to an object newname, all in container
2926ba597c5SAnurag S. Maskey  * dbname.
2936ba597c5SAnurag S. Maskey  */
2946ba597c5SAnurag S. Maskey nwam_error_t
nwam_copy(const char * dbname,struct nwam_handle * oldhp,const char * newname,struct nwam_handle ** newhpp)2956ba597c5SAnurag S. Maskey nwam_copy(const char *dbname, struct nwam_handle *oldhp, const char *newname,
2966ba597c5SAnurag S. Maskey     struct nwam_handle **newhpp)
2976ba597c5SAnurag S. Maskey {
2986ba597c5SAnurag S. Maskey 	nwam_error_t err;
2996ba597c5SAnurag S. Maskey 	struct nwam_handle *hp;
3006ba597c5SAnurag S. Maskey 
3016ba597c5SAnurag S. Maskey 	assert(oldhp != NULL && newname != NULL && newhpp != NULL);
3026ba597c5SAnurag S. Maskey 
3036ba597c5SAnurag S. Maskey 	if (nwam_read(oldhp->nwh_object_type, dbname, newname, 0, &hp)
3046ba597c5SAnurag S. Maskey 	    == NWAM_SUCCESS) {
3056ba597c5SAnurag S. Maskey 		nwam_free(hp);
3066ba597c5SAnurag S. Maskey 		return (NWAM_ENTITY_EXISTS);
3076ba597c5SAnurag S. Maskey 	}
3086ba597c5SAnurag S. Maskey 
3096ba597c5SAnurag S. Maskey 	if ((err = nwam_handle_create(oldhp->nwh_object_type, newname, newhpp))
3106ba597c5SAnurag S. Maskey 	    != NWAM_SUCCESS)
3116ba597c5SAnurag S. Maskey 		return (err);
3126ba597c5SAnurag S. Maskey 	if ((err = nwam_dup_object_list(oldhp->nwh_data,
3136ba597c5SAnurag S. Maskey 	    &((*newhpp)->nwh_data))) != NWAM_SUCCESS) {
3146ba597c5SAnurag S. Maskey 		nwam_free(*newhpp);
3156ba597c5SAnurag S. Maskey 		*newhpp = NULL;
3166ba597c5SAnurag S. Maskey 		return (err);
3176ba597c5SAnurag S. Maskey 	}
3186ba597c5SAnurag S. Maskey 
3196ba597c5SAnurag S. Maskey 	return (NWAM_SUCCESS);
3206ba597c5SAnurag S. Maskey }