changeset 10020:ff5f2b3729b6

6848927 sulogin accepts empty username 6446994 'profiles -l' doesn't list all commands if profile has both solaris and suser policies
author Joep Vesseur <Joep.Vesseur@Sun.COM>
date Thu, 02 Jul 2009 15:13:49 +0200
parents 1e29dbfb7b3b
children a41c569bdaca
files usr/src/cmd/nscd/nscd_switch.c usr/src/cmd/profiles/profiles.c usr/src/cmd/sulogin/sulogin.c usr/src/head/exec_attr.h usr/src/lib/libnsl/nss/getexecattr.c usr/src/lib/libsecdb/common/getexecattr.c usr/src/lib/nsswitch/files/common/getexecattr.c usr/src/lib/nsswitch/ldap/common/getexecattr.c usr/src/lib/nsswitch/nis/common/getexecattr.c usr/src/lib/nsswitch/nisplus/common/getexecattr.c
diffstat 10 files changed, 93 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/nscd/nscd_switch.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/cmd/nscd/nscd_switch.c	Thu Jul 02 15:13:49 2009 +0200
@@ -398,7 +398,7 @@
 	char			*me = "try_local";
 
 	if (strcmp(NSCD_NSW_DB_NAME(dbi), NSS_DBNAM_EXECATTR) == 0) {
-		if ((ep = ap->key.attrp) != NULL && ep->search_flag == GET_ALL)
+		if ((ep = ap->key.attrp) != NULL && IS_GET_ALL(ep->search_flag))
 			rc = 1;
 	}
 
--- a/usr/src/cmd/profiles/profiles.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/cmd/profiles/profiles.c	Thu Jul 02 15:13:49 2009 +0200
@@ -145,7 +145,7 @@
 			} else {
 				if (print_flag & PRINT_LONG) {
 					exec = getexecuser(username, KV_COMMAND,
-					    NULL, GET_ALL);
+					    NULL, GET_ALL|__SEARCH_ALL_POLS);
 					print_profs_long(exec);
 					free_execattr(exec);
 				} else {
@@ -175,7 +175,8 @@
 	int		profcnt = 0;
 
 	if (print_flag & PRINT_LONG) {
-		exec = getexecuser(user->name, KV_COMMAND, NULL, GET_ALL);
+		exec = getexecuser(user->name, KV_COMMAND, NULL,
+		    GET_ALL|__SEARCH_ALL_POLS);
 		if (exec == NULL) {
 			status = EXIT_NON_FATAL;
 		}
--- a/usr/src/cmd/sulogin/sulogin.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/cmd/sulogin/sulogin.c	Thu Jul 02 15:13:49 2009 +0200
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -483,16 +483,19 @@
 	sanitize_tty(fileno(stdin));
 
 	for (;;) {
-		(void) printf("\nEnter user name for system maintenance "
-		    "(control-d to bypass): ");
-		if ((user = sulogin_getinput(devname, ECHOON)) == NULL) {
-			/* signal other children to exit */
-			(void) sigsend(P_PID, masterpid, SIGUSR1);
-			/* ^D, so straight to default init state */
-			exit(EXIT_FAILURE);
-		}
-		(void) printf("\nEnter %s password for system maintenance "
-		    "(control-d to bypass): ", user);
+		do {
+			(void) printf("\nEnter user name for system "
+			    "maintenance (control-d to bypass): ");
+			user = sulogin_getinput(devname, ECHOON);
+			if (user == NULL) {
+				/* signal other children to exit */
+				(void) sigsend(P_PID, masterpid, SIGUSR1);
+				/* ^D, so straight to default init state */
+				exit(EXIT_FAILURE);
+			}
+		} while (user[0] == '\0');
+		(void) printf("Enter %s password (control-d to bypass): ",
+		    user);
 
 		if ((pass = sulogin_getinput(devname, ECHOOFF)) == NULL) {
 			/* signal other children to exit */
--- a/usr/src/head/exec_attr.h	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/head/exec_attr.h	Thu Jul 02 15:13:49 2009 +0200
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,15 +19,13 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 1999-2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef	_EXEC_ATTR_H
 #define	_EXEC_ATTR_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -65,9 +62,26 @@
  * Some macros used internally by the nsswitch code
  */
 
-#define	GET_ONE		0	/* get only one exec_attr from list */
-#define	GET_ALL		1	/* get all matching exec_attrs in list */
+/*
+ * These macros are bitmasks. GET_ONE and GET_ALL are bitfield 0
+ * and thus mutually exclusive. __SEARCH_ALL_POLLS is bitfield
+ * 1 and can be logically ORed with GET_ALL if one wants to get
+ * all matching profiles from all policies, not just the ones from
+ * the currently active policy
+ *
+ * Testing for these values should be done using the IS_* macros
+ * defined below.
+ */
+#define	GET_ONE			0
+#define	GET_ALL			1
+#define	__SEARCH_ALL_POLS	2
 
+/* get only one exec_attr from list */
+#define	IS_GET_ONE(f) (((f) & GET_ALL) == 0)
+/* get all matching exec_attrs in list */
+#define	IS_GET_ALL(f) (((f) & GET_ALL) == 1)
+/* search all existing policies */
+#define	IS_SEARCH_ALL(f) (((f) & __SEARCH_ALL_POLS) == __SEARCH_ALL_POLS)
 
 /*
  * Key words used in the exec_attr database
--- a/usr/src/lib/libnsl/nss/getexecattr.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/lib/libnsl/nss/getexecattr.c	Thu Jul 02 15:13:49 2009 +0200
@@ -18,14 +18,11 @@
  *
  * CDDL HEADER END
  */
-
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "mt.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -187,7 +184,7 @@
 	(void) strncpy(policy_buf, DEFAULT_POLICY, BUFSIZ);
 
 retry_policy:
-	_priv_exec.policy = policy_buf;
+	_priv_exec.policy = IS_SEARCH_ALL(search_flag) ? empty : policy_buf;
 	_priv_exec.search_flag = search_flag;
 	_priv_exec.head_exec = NULL;
 	_priv_exec.prev_exec = NULL;
@@ -247,7 +244,7 @@
 					    &arg);
 					if (pexec_root.s != NULL)
 						_nss_db_state_destr(
-							pexec_root.s);
+						    pexec_root.s);
 				}
 				if (prof_root.s != NULL)
 					_nss_db_state_destr(prof_root.s);
@@ -267,7 +264,8 @@
 	 * fall back to the old "suser" policy.  The nameservice is
 	 * shared between different OS releases.
 	 */
-	if (res == NSS_NOTFOUND && strcmp(policy_buf, DEFAULT_POLICY) == 0) {
+	if (!IS_SEARCH_ALL(search_flag) &&
+	    (res == NSS_NOTFOUND && strcmp(policy_buf, DEFAULT_POLICY) == 0)) {
 		(void) strlcpy(policy_buf, SUSER_POLICY, BUFSIZ);
 		goto retry_policy;
 	}
--- a/usr/src/lib/libsecdb/common/getexecattr.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/lib/libsecdb/common/getexecattr.c	Thu Jul 02 15:13:49 2009 +0200
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <stdio.h>
 #include <string.h>
@@ -82,27 +80,23 @@
 	(void) memset(unique, 0, NSS_BUFLEN_EXECATTR);
 	(void) memset(&exec, 0, sizeof (execstr_t));
 
-	if ((search_flag != GET_ONE) && (search_flag != GET_ALL)) {
+	if (!IS_GET_ONE(search_flag) && !IS_GET_ALL(search_flag)) {
 		return (NULL);
 	}
 
 	if ((name == NULL) && (type == NULL) && (id == NULL)) {
 		setexecattr();
-		switch (search_flag) {
-		case GET_ONE:
+		if (IS_GET_ONE(search_flag)) {
 			head = getexecattr();
-			break;
-		case GET_ALL:
+		} else if (IS_GET_ALL(search_flag)) {
 			head = getexecattr();
 			prev = head;
 			while (prev != NULL) {
 				prev->next = getexecattr();
 				prev = prev->next;
 			};
-			break;
-		default:
+		} else {
 			head = NULL;
-			break;
 		}
 		endexecattr();
 		return (head);
@@ -120,7 +114,6 @@
 	return (execstr2attr(tmp));
 }
 
-
 execattr_t *
 getexecuser(const char *username, const char *type, const char *id,
     int search_flag)
@@ -133,7 +126,7 @@
 	execattr_t	*prev =  NULL;
 	execattr_t	*new = NULL;
 
-	if ((search_flag != GET_ONE) && (search_flag != GET_ALL)) {
+	if (!IS_GET_ONE(search_flag) && !IS_GET_ALL(search_flag)) {
 		return (NULL);
 	}
 
@@ -144,12 +137,10 @@
 		if (utmp == NULL) {
 			return (head);
 		}
-		switch (search_flag) {
-		case GET_ONE:
+		if (IS_GET_ONE(search_flag)) {
 			head = userprof((const char *)(utmp->name), type, id,
 			    search_flag);
-			break;
-		case GET_ALL:
+		} else if (IS_GET_ALL(search_flag)) {
 			head = userprof((const char *)(utmp->name), type, id,
 			    search_flag);
 			if (head != NULL) {
@@ -169,10 +160,8 @@
 					}
 				}
 			}
-			break;
-		default:
+		} else {
 			head = NULL;
-			break;
 		}
 		enduserattr();
 	} else {
@@ -297,10 +286,10 @@
 		profname = profArray[i];
 		if ((exec = getexecprof(profname, type, id, search_flag)) !=
 		    NULL) {
-			if (search_flag == GET_ONE) {
+			if (IS_GET_ONE(search_flag)) {
 				head = exec;
 				break;
-			} else if (search_flag == GET_ALL) {
+			} else if (IS_GET_ALL(search_flag)) {
 				if (head == NULL) {
 					head = exec;
 					prev = get_tail(head);
--- a/usr/src/lib/nsswitch/files/common/getexecattr.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/lib/nsswitch/files/common/getexecattr.c	Thu Jul 02 15:13:49 2009 +0200
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdlib.h>
 #include "files_common.h"
 #include <time.h>
@@ -80,7 +78,7 @@
 		if (keyp) {
 			/* compare field */
 			while (*keyp && linep < limit &&
-				*linep != ':' && *keyp == *linep) {
+			    *linep != ':' && *keyp == *linep) {
 				keyp++;
 				linep++;
 			}
@@ -220,7 +218,8 @@
 		default:
 			break;
 		}
-		if ((strstr(instr, _priv_exec->policy) == NULL) ||
+		if (((_priv_exec->policy != NULL) &&
+		    (strstr(instr, _priv_exec->policy) == NULL)) ||
 		    ((_priv_exec->type != NULL) &&
 		    (strstr(instr, _priv_exec->type) == NULL)))
 				continue;
@@ -262,10 +261,10 @@
 		    argp->buf.buffer, argp->buf.buflen);
 		if (parse_stat == NSS_STR_PARSE_SUCCESS) {
 			argp->returnval = (argp->buf.result != NULL)?
-					argp->buf.result : argp->buf.buffer;
+			    argp->buf.result : argp->buf.buffer;
 			argp->returnlen = linelen;
 			res = NSS_SUCCESS;
-			if (_priv_exec->search_flag == GET_ONE) {
+			if (IS_GET_ONE(_priv_exec->search_flag)) {
 				break;
 			} else if (_doexeclist(argp) == 0) {
 				res = NSS_UNAVAIL;
@@ -387,8 +386,6 @@
     const char *dummy7)
 {
 	return (_nss_files_constr(execattr_ops,
-		sizeof (execattr_ops)/sizeof (execattr_ops[0]),
-		EXECATTR_FILENAME,
-		NSS_LINELEN_EXECATTR,
-		NULL));
+	    sizeof (execattr_ops)/sizeof (execattr_ops[0]),
+	    EXECATTR_FILENAME, NSS_LINELEN_EXECATTR, NULL));
 }
--- a/usr/src/lib/nsswitch/ldap/common/getexecattr.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/lib/nsswitch/ldap/common/getexecattr.c	Thu Jul 02 15:13:49 2009 +0200
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <secdb.h>
 #include <exec_attr.h>
 #include "ldap_common.h"
@@ -282,7 +280,7 @@
 
 	name = __ns_ldap_getAttr(result->entry, _EXEC_NAME);
 	if (name == NULL || name[0] == NULL ||
-			(strlen(name[0]) < 1)) {
+	    (strlen(name[0]) < 1)) {
 		status = NSS_STR_PARSE_PARSE;
 		goto result_exec2str;
 	}
@@ -326,8 +324,8 @@
 
 	/* 7 = 6 ':' + 1 '\0' */
 	len = strlen(name[0]) + strlen(policy_str) + strlen(type_str) +
-		strlen(res1_str) + strlen(res2_str) + strlen(id_str) +
-		strlen(attr_str) + 7;
+	    strlen(res1_str) + strlen(res2_str) + strlen(id_str) +
+	    strlen(attr_str) + 7;
 
 	if (len > argp->buf.buflen) {
 		status = NSS_STR_PARSE_ERANGE;
@@ -343,8 +341,8 @@
 		buffer = argp->buf.buffer;
 
 	(void) snprintf(buffer, len, "%s:%s:%s:%s:%s:%s:%s",
-			name[0], policy_str, type_str, res1_str,
-			res2_str, id_str, attr_str);
+	    name[0], policy_str, type_str, res1_str,
+	    res2_str, id_str, attr_str);
 	/* The front end marshaller does not need the trailing null */
 	if (argp->buf.result != NULL)
 		be->buflen = strlen(buffer);
@@ -376,7 +374,7 @@
 		case NSS_STR_PARSE_SUCCESS:
 			argp->returnval = argp->buf.result;
 			nss_stat = NSS_SUCCESS;
-			if (_priv_exec->search_flag == GET_ALL) {
+			if (IS_GET_ALL(_priv_exec->search_flag)) {
 				if (_doexeclist(argp) == 0) {
 					nss_stat = NSS_UNAVAIL;
 				}
@@ -394,7 +392,7 @@
 			break;
 		}
 
-		if ((_priv_exec->search_flag == GET_ONE) ||
+		if (IS_GET_ONE(_priv_exec->search_flag) ||
 		    (nss_stat != NSS_SUCCESS)) {
 			break;
 		}
@@ -491,7 +489,7 @@
 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
 	int		stat, nss_stat = NSS_SUCCESS;
 
-	if (_priv_exec->search_flag == GET_ONE) {
+	if (IS_GET_ONE(_priv_exec->search_flag)) {
 		/* ns_ldap_entry_t -> file format */
 		stat = (*be->ldapobj2str)(be, argp);
 
@@ -624,6 +622,6 @@
 	    "\n[getexecattr.c: _nss_ldap_exec_attr_constr]\n");
 #endif
 	return ((nss_backend_t *)_nss_ldap_constr(execattr_ops,
-		sizeof (execattr_ops)/sizeof (execattr_ops[0]), _EXECATTR,
-		exec_attrs, _nss_ldap_exec2str));
+	    sizeof (execattr_ops)/sizeof (execattr_ops[0]), _EXECATTR,
+	    exec_attrs, _nss_ldap_exec2str));
 }
--- a/usr/src/lib/nsswitch/nis/common/getexecattr.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/lib/nsswitch/nis/common/getexecattr.c	Thu Jul 02 15:13:49 2009 +0200
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
@@ -150,14 +148,14 @@
 			if ((strbuf = strdup(instr)) == NULL)
 				res = NSS_UNAVAIL;
 			check_matched = check_match_strbuf(argp,
-				strbuf, check_policy);
+			    strbuf, check_policy);
 		} else {
 			argp->returnval = argp->buf.result;
 			check_matched = check_match(argp, check_policy);
 		}
 		if (check_matched) {
 			res = NSS_SUCCESS;
-			if (_priv_exec->search_flag == GET_ALL) {
+			if (IS_GET_ALL(_priv_exec->search_flag)) {
 				if (_doexeclist(argp) == 0) {
 					res = NSS_UNAVAIL;
 				}
@@ -242,7 +240,7 @@
 	switch (res) {
 	case NSS_SUCCESS:
 		*(eargp->yp_status) = 0;
-		stop_cb = (_priv_exec->search_flag == GET_ONE);
+		stop_cb = IS_GET_ONE(_priv_exec->search_flag);
 		break;
 	case NSS_UNAVAIL:
 		*(eargp->yp_status) = YPERR_KEY;
@@ -321,7 +319,7 @@
 		 * do exactly the same thing.
 		 */
 		ypstatus = __yp_all_cflookup((char *)(be->domain),
-			(char *)(be->enum_map), &cback, 0);
+		    (char *)(be->enum_map), &cback, 0);
 
 		/*
 		 * For GET_ALL, check if we found anything at all.
@@ -457,6 +455,6 @@
     const char *dummy7)
 {
 	return (_nss_nis_constr(execattr_ops,
-		sizeof (execattr_ops)/sizeof (execattr_ops[0]),
-		NIS_MAP_EXECATTR));
+	    sizeof (execattr_ops)/sizeof (execattr_ops[0]),
+	    NIS_MAP_EXECATTR));
 }
--- a/usr/src/lib/nsswitch/nisplus/common/getexecattr.c	Wed Jul 01 20:57:22 2009 -0700
+++ b/usr/src/lib/nsswitch/nisplus/common/getexecattr.c	Thu Jul 02 15:13:49 2009 +0200
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
@@ -122,11 +120,8 @@
 		parsestat = NSS_STR_PARSE_PARSE;
 		goto fail;
 	}
-	parsestat = (*argp->str2ent)(be->buffer,
-		be->buflen,
-		argp->buf.result,
-		argp->buf.buffer,
-		argp->buf.buflen);
+	parsestat = (*argp->str2ent)(be->buffer, be->buflen, argp->buf.result,
+	    argp->buf.buffer, argp->buf.buflen);
 	if (parsestat == NSS_STR_PARSE_SUCCESS) {
 		if (be->buffer != NULL) {
 			free(be->buffer);
@@ -140,7 +135,7 @@
 			argp->returnval = argp->buf.buffer;
 			argp->returnlen = strlen(argp->buf.buffer);
 		}
-		if (_priv_exec->search_flag == GET_ALL)
+		if (IS_GET_ALL(_priv_exec->search_flag))
 			if (_doexeclist(argp) == 0)
 				return (NSS_UNAVAIL);
 		return (NSS_SUCCESS);
@@ -228,7 +223,7 @@
 	*(eargp->resp) = res;
 	switch (res) {
 	case NSS_SUCCESS:
-		status = (_priv_exec->search_flag == GET_ONE);
+		status = IS_GET_ONE(_priv_exec->search_flag);
 		break;
 	case NSS_UNAVAIL:
 		status = 1;
@@ -454,8 +449,7 @@
 	__NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_TYPE, typelen, type);
 
 	/* policy */
-	__NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_POLICY,
-		policylen, policy);
+	__NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_POLICY, policylen, policy);
 
 	/* reserved field 1 */
 	__NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_RES1, res1len, res1);
@@ -469,8 +463,8 @@
 	/* key-value pairs of attributes */
 	__NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_ATTR, attrlen, attr);
 
-	buflen = namelen + policylen + typelen + res1len + res2len
-		+ idlen + attrlen + 7;
+	buflen = namelen + policylen + typelen + res1len + res2len +
+	    idlen + attrlen + 7;
 	if (argp->buf.result != NULL) {
 		if ((be->buffer = calloc(1, buflen)) == NULL)
 			return (NSS_STR_PARSE_PARSE);
@@ -485,7 +479,7 @@
 		(void) memset(buffer, 0, buflen);
 	}
 	(void) snprintf(buffer, buflen, "%s:%s:%s:%s:%s:%s:%s",
-		name, policy, type, res1, res2, id, attr);
+	    name, policy, type, res1, res2, id, attr);
 #ifdef DEBUG
 	(void) fprintf(stdout, "execattr [%s]\n", buffer);
 	(void) fflush(stdout);
@@ -514,7 +508,6 @@
     const char *dummy7)
 {
 	return (_nss_nisplus_constr(execattr_ops,
-		sizeof (execattr_ops)/sizeof (execattr_ops[0]),
-		EXECATTR_TBLNAME,
-		nis_object2execstr));
+	    sizeof (execattr_ops)/sizeof (execattr_ops[0]),
+	    EXECATTR_TBLNAME, nis_object2execstr));
 }