예제 #1
0
static int
add_netgroup_member_entry(ns_ldap_entry_t *entry, netgroup_table_t *tab)
{
	char		**attrs;
	char		**a;

	attrs = __ns_ldap_getAttr(entry, _N_MEMBER);
	if (attrs == NULL || *attrs == NULL)
		return (0);

	for (a = attrs; *a != NULL; a++) {}

	do {
		a--;
		if (add_netgroup_name(*a, tab) != 0)
			return (-1);
	} while (a > attrs);
	return (0);
}
예제 #2
0
static int
_nss_ldap_shadow2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
{
	int		nss_result;
	int		buflen = 0;
	int		shadow_update_enabled;
	unsigned long	len = 0L;
	char		*tmp, *buffer = NULL;
	char		*pw_passwd = NULL;
	ns_ldap_result_t	*result = be->result;
	char		**uid, **passwd, **last, **smin, **smax;
	char		**warning, **inactive, **expire, **flag;
	char		*last_str, *min_str, *max_str, *warning_str;
	char		*inactive_str, *expire_str, *flag_str;

	if (result == NULL)
		return (NSS_STR_PARSE_PARSE);
	buflen = argp->buf.buflen;

	nss_result = NSS_STR_PARSE_SUCCESS;
	(void) memset(argp->buf.buffer, 0, buflen);

	uid = __ns_ldap_getAttr(result->entry, _S_UID);
	if (uid == NULL || uid[0] == NULL || (strlen(uid[0]) < 1)) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_spd2str;
	}
	len += strlen(uid[0]);

	passwd = __ns_ldap_getAttr(result->entry, _S_USERPASSWORD);
	if (passwd == NULL || passwd[0] == NULL) {
		/*
		 * ACL does not allow userpassword to return or
		 * userpassword is not defined
		 */
		pw_passwd = NOPWDRTR;
	} else if (strcmp(passwd[0], "") == 0) {
		/*
		 * An empty password is not supported
		 */
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_spd2str;
	} else {
		if ((tmp = strstr(passwd[0], "{crypt}")) != NULL ||
		    (tmp = strstr(passwd[0], "{CRYPT}")) != NULL) {
			if (tmp != passwd[0])
				pw_passwd = NOPWDRTR;
			else {
				pw_passwd = tmp + strlen("{crypt}");
				if (strcmp(pw_passwd,
				    NS_LDAP_NO_UNIX_PASSWORD) == 0)
					*pw_passwd = '\0';
			}
		} else {
		/* mark password as not retrievable */
			pw_passwd = NOPWDRTR;
		}
	}
	len += strlen(pw_passwd);

	/*
	 * If shadow update is not enabled, ignore the following
	 * password aging related attributes:
	 * -- shadowlastchange
	 * -- shadowmin
	 * -- shadowmax
	 * -- shadowwarning
	 * -- shadowinactive
	 * -- shadowexpire
	 * When shadow update is not enabled, the LDAP naming
	 * service does not support the password aging fields
	 * defined in the shadow structure. These fields, sp_lstchg,
	 * sp_min, sp_max, sp_warn, sp_inact, and sp_expire,
	 * will be set to -1 by the front end marshaller.
	 */

	shadow_update_enabled = __ns_ldap_is_shadow_update_enabled();
	if (shadow_update_enabled) {
		last = __ns_ldap_getAttr(result->entry, _S_LASTCHANGE);
		if (last == NULL || last[0] == NULL)
			last_str = _NO_VALUE;
		else
			last_str = last[0];
		len += strlen(last_str);

		smin = __ns_ldap_getAttr(result->entry, _S_MIN);
		if (smin == NULL || smin[0] == NULL)
			min_str = _NO_VALUE;
		else
			min_str = smin[0];
		len += strlen(min_str);

		smax = __ns_ldap_getAttr(result->entry, _S_MAX);
		if (smax == NULL || smax[0] == NULL)
			max_str = _NO_VALUE;
		else
			max_str = smax[0];
		len += strlen(max_str);

		warning = __ns_ldap_getAttr(result->entry, _S_WARNING);
		if (warning == NULL || warning[0] == NULL)
			warning_str = _NO_VALUE;
		else
			warning_str = warning[0];
		len += strlen(warning_str);

		inactive = __ns_ldap_getAttr(result->entry, _S_INACTIVE);
		if (inactive == NULL || inactive[0] == NULL)
			inactive_str = _NO_VALUE;
		else
			inactive_str = inactive[0];
		len += strlen(inactive_str);

		expire = __ns_ldap_getAttr(result->entry, _S_EXPIRE);
		if (expire == NULL || expire[0] == NULL)
			expire_str = _NO_VALUE;
		else
			expire_str = expire[0];
		len += strlen(expire_str);
	}

	flag = __ns_ldap_getAttr(result->entry, _S_FLAG);
	if (flag == NULL || flag[0] == NULL)
		flag_str = _NO_VALUE;
	else
		flag_str = flag[0];

	/* 9 = 8 ':' + 1 '\0' */
	len += strlen(flag_str) + 9;

	if (len > buflen) {
		nss_result = NSS_STR_PARSE_ERANGE;
		goto result_spd2str;
	}

	if (argp->buf.result != NULL) {
		be->buffer = calloc(1, len);
		if (be->buffer == NULL) {
			nss_result = NSS_STR_PARSE_PARSE;
			goto result_spd2str;
		}
		buffer = be->buffer;
	} else
		buffer = argp->buf.buffer;

	if (shadow_update_enabled) {
		(void) snprintf(buffer, len, "%s:%s:%s:%s:%s:%s:%s:%s:%s",
		    uid[0], pw_passwd, last_str, min_str, max_str, warning_str,
		    inactive_str, expire_str, flag_str);
	} else {
		(void) snprintf(buffer, len, "%s:%s:::::::%s",
		    uid[0], pw_passwd, flag_str);
	}

	/* The front end marhsaller doesn't need the trailing null */
	if (argp->buf.result != NULL)
		be->buflen = strlen(be->buffer);
result_spd2str:

	(void) __ns_ldap_freeResult(&be->result);
	return ((int)nss_result);
}
예제 #3
0
static int
_nss_ldap_group2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
{
	int		i;
	int		nss_result;
	int		buflen = 0, len;
	int		firstime = 1;
	char		*buffer = NULL;
	ns_ldap_result_t	*result = be->result;
	char		**gname, **passwd, **gid, *password, *end;
	char		gid_nobody[NOBODY_STR_LEN];
	char		*gid_nobody_v[1];
	char		*member_str, *strtok_state;
	ns_ldap_attr_t	*members;

	(void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY);
	gid_nobody_v[0] = gid_nobody;

	if (result == NULL)
		return (NSS_STR_PARSE_PARSE);
	buflen = argp->buf.buflen;

	if (argp->buf.result != NULL) {
		if ((be->buffer = calloc(1, buflen)) == NULL) {
			nss_result = NSS_STR_PARSE_PARSE;
			goto result_grp2str;
		}
		buffer = be->buffer;
	} else
		buffer = argp->buf.buffer;

	nss_result = NSS_STR_PARSE_SUCCESS;
	(void) memset(buffer, 0, buflen);

	gname = __ns_ldap_getAttr(result->entry, _G_NAME);
	if (gname == NULL || gname[0] == NULL || (strlen(gname[0]) < 1)) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_grp2str;
	}
	passwd = __ns_ldap_getAttr(result->entry, _G_PASSWD);
	if (passwd == NULL || passwd[0] == NULL || (strlen(passwd[0]) == 0)) {
		/* group password could be NULL, replace it with "" */
		password = _NO_PASSWD_VAL;
	} else {
		/*
		 * Preen "{crypt}" if necessary.
		 * If the password does not include the {crypt} prefix
		 * then the password may be plain text.  And thus
		 * perhaps crypt(3c) should be used to encrypt it.
		 * Currently the password is copied verbatim.
		 */
		if (strncasecmp(passwd[0], _CRYPT, strlen(_CRYPT)) == 0)
			password = passwd[0] + strlen(_CRYPT);
		else
			password = passwd[0];
	}
	gid = __ns_ldap_getAttr(result->entry, _G_GID);
	if (gid == NULL || gid[0] == NULL || (strlen(gid[0]) < 1)) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_grp2str;
	}
	/* Validate GID */
	if (strtoul(gid[0], &end, 10) > MAXUID)
		gid = gid_nobody_v;
	len = snprintf(buffer, buflen, "%s:%s:%s:", gname[0], password, gid[0]);
	TEST_AND_ADJUST(len, buffer, buflen, result_grp2str);

	members = __ns_ldap_getAttrStruct(result->entry, _G_MEM);
	if (members == NULL || members->attrvalue == NULL) {
		/* no member is fine, skip processing the member list */
		goto nomember;
	}

	for (i = 0; i < members->value_count; i++) {
		if (members->attrvalue[i] == NULL) {
			nss_result = NSS_STR_PARSE_PARSE;
			goto result_grp2str;
		}
		/*
		 * If we find an '=' in the member attribute value, treat it as
		 * a DN, otherwise as a username.
		 */
		if (member_str = strchr(members->attrvalue[i], '=')) {
			member_str++; /* skip over the '=' */
			/* Fail if we can't pull a username out of the RDN */
			if (! (member_str = strtok_r(member_str,
			    ",", &strtok_state))) {
				nss_result = NSS_STR_PARSE_PARSE;
				goto result_grp2str;
			}
		} else {
			member_str = members->attrvalue[i];
		}
		if (*member_str != '\0') {
			if (firstime) {
				len = snprintf(buffer, buflen, "%s",
				    member_str);
				TEST_AND_ADJUST(len, buffer, buflen,
				    result_grp2str);
				firstime = 0;
			} else {
				len = snprintf(buffer, buflen, ",%s",
				    member_str);
				TEST_AND_ADJUST(len, buffer, buflen,
				    result_grp2str);
			}
		}
	}
nomember:
	/* The front end marshaller doesn't need the trailing nulls */
	if (argp->buf.result != NULL)
		be->buflen = strlen(be->buffer);
result_grp2str:
	(void) __ns_ldap_freeResult(&be->result);
	return (nss_result);
}
예제 #4
0
static nss_status_t
getbymember(ldap_backend_ptr be, void *a)
{
	int			i, j, k;
	int			gcnt = (int)0;
	char			**groupvalue, **membervalue, *member_str;
	char			*strtok_state;
	nss_status_t		lstat;
	struct nss_groupsbymem	*argp = (struct nss_groupsbymem *)a;
	char			searchfilter[SEARCHFILTERLEN];
	char			userdata[SEARCHFILTERLEN];
	char			name[SEARCHFILTERLEN];
	ns_ldap_result_t	*result;
	ns_ldap_entry_t		*curEntry;
	char			*username, **dn_attr, *dn;
	gid_t			gid;
	int			ret;

	if (strcmp(argp->username, "") == 0 ||
	    strcmp(argp->username, "root") == 0)
		return ((nss_status_t)NSS_NOTFOUND);

	if (_ldap_filter_name(name, argp->username, sizeof (name)) != 0)
		return ((nss_status_t)NSS_NOTFOUND);

	ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWNAM, name);
	if (ret >= sizeof (searchfilter) || ret < 0)
		return ((nss_status_t)NSS_NOTFOUND);

	ret = snprintf(userdata, sizeof (userdata), _F_GETPWNAM_SSD, name);
	if (ret >= sizeof (userdata) || ret < 0)
		return ((nss_status_t)NSS_NOTFOUND);

	/*
	 * Look up the user DN in ldap. If it's not found, search solely by
	 * username.
	 */
	lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL,
	    _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata);
	if (lstat != (nss_status_t)NS_LDAP_SUCCESS)
		return ((nss_status_t)lstat);

	if (be->result == NULL ||
	    !(dn_attr = __ns_ldap_getAttr(be->result->entry, "dn")))
		dn = name;
	else
		dn = dn_attr[0];

	ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETGRMEM, name,
	    dn);
	if (ret >= sizeof (searchfilter) || ret < 0)
		return ((nss_status_t)NSS_NOTFOUND);

	ret = snprintf(userdata, sizeof (userdata), _F_GETGRMEM_SSD, name,
	    dn);
	if (ret >= sizeof (userdata) || ret < 0)
		return ((nss_status_t)NSS_NOTFOUND);

	/*
	 * Free up resources from user DN search before performing group
	 * search.
	 */
	(void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result);

	gcnt = (int)argp->numgids;
	lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL,
	    _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata);
	if (lstat != (nss_status_t)NS_LDAP_SUCCESS)
		return ((nss_status_t)lstat);
	if (be->result == NULL)
		return (NSS_NOTFOUND);
	username = (char *)argp->username;
	result = (ns_ldap_result_t *)be->result;
	curEntry = (ns_ldap_entry_t *)result->entry;
	for (i = 0; i < result->entries_count && curEntry != NULL; i++) {
		membervalue = __ns_ldap_getAttr(curEntry, "memberUid");
		if (membervalue == NULL) {
			curEntry = curEntry->next;
			continue;
		}
		for (j = 0; membervalue[j]; j++) {
			/*
			 * If we find an '=' in the member attribute
			 * value, treat it as a DN, otherwise as a
			 * username.
			 */
			if (member_str = strchr(membervalue[j], '=')) {
				member_str++; /* skip over the '=' */
				member_str = strtok_r(member_str, ",",
				    &strtok_state);
			} else {
				member_str = membervalue[j];
			}
			if (member_str != NULL &&
			    strcmp(member_str, username) == 0) {
				groupvalue = __ns_ldap_getAttr(curEntry,
				    "gidnumber");
				if (groupvalue == NULL ||
				    groupvalue[0] == NULL) {
					/* Drop this group from the list */
					break;
				}
				errno = 0;
				gid = (gid_t)strtol(groupvalue[0],
				    (char **)NULL, 10);

				if (errno == 0 &&
				    argp->numgids < argp->maxgids) {
					for (k = 0; k < argp->numgids; k++) {
						if (argp->gid_array[k] == gid)
							/* already exists */
							break;
					}
					if (k == argp->numgids)
						argp->gid_array[argp->numgids++]
						    = gid;
				}
				break;
			}
		}
		curEntry = curEntry->next;
	}

	(void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result);
	if (gcnt == argp->numgids)
		return ((nss_status_t)NSS_NOTFOUND);

	/*
	 * Return NSS_SUCCESS only if array is full.
	 * Explained in <nss_dbdefs.h>.
	 */
	return ((nss_status_t)((argp->numgids == argp->maxgids)
	    ? NSS_SUCCESS
	    : NSS_NOTFOUND));
}
예제 #5
0
/*
 * _nss_ldap_passwd2str is the data marshaling method for the passwd getXbyY
 * (e.g., getbyuid(), getbyname(), getpwent()) backend processes. This method is
 * called after a successful ldap search has been performed. This method will
 * parse the ldap search values into the file format.
 * e.g.
 *
 * nobody:x:60001:60001:Nobody:/:
 *
 */
static int
_nss_ldap_passwd2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
{
	int		nss_result;
	int		buflen = 0;
	unsigned long	str_len = 0L;
	char		*buffer = NULL;
	ns_ldap_result_t	*result = be->result;
	ns_ldap_entry_t	*entry;
	char		**uid_v, **uidn_v, **gidn_v;
	char		**gecos_v, **homedir_v, **shell_v;
	char		*NULL_STR = "";
	char		uid_nobody[NOBODY_STR_LEN];
	char		gid_nobody[NOBODY_STR_LEN], *end;
	char		*uid_nobody_v[1], *gid_nobody_v[1];

	(void) snprintf(uid_nobody, sizeof (uid_nobody), "%u", UID_NOBODY);
	uid_nobody_v[0] = uid_nobody;
	(void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY);
	gid_nobody_v[0] = gid_nobody;

	if (result == NULL)
		return (NSS_STR_PARSE_PARSE);

	entry = result->entry;

	buflen = argp->buf.buflen;
	buffer = argp->buf.buffer;

	nss_result = NSS_STR_PARSE_SUCCESS;
	(void) memset(buffer, 0, buflen);

	/* 8 = 6 ':' + 1 '\0' + 1 'x' */
	buflen -=  8;

	uid_v = __ns_ldap_getAttr(entry, _PWD_UID);
	uidn_v = __ns_ldap_getAttr(entry, _PWD_UIDNUMBER);
	gidn_v = __ns_ldap_getAttr(entry, _PWD_GIDNUMBER);
	if (uid_v == NULL || uidn_v == NULL || gidn_v == NULL ||
	    uid_v[0] == NULL || uidn_v[0] == NULL || gidn_v[0] == NULL) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_pwd2str;
	}
	/* Validate UID and GID */
	if (strtoul(uidn_v[0], &end, 10) > MAXUID)
		uidn_v = uid_nobody_v;
	if (strtoul(gidn_v[0], &end, 10) > MAXUID)
		gidn_v = gid_nobody_v;
	str_len = strlen(uid_v[0]) + strlen(uidn_v[0]) + strlen(gidn_v[0]);
	if (str_len >  buflen) {
		nss_result = NSS_STR_PARSE_ERANGE;
		goto result_pwd2str;
	}

	gecos_v = __ns_ldap_getAttr(entry, _PWD_GECOS);
	if (gecos_v == NULL || gecos_v[0] == NULL || *gecos_v[0] == '\0')
		gecos_v = &NULL_STR;
	else
		str_len += strlen(gecos_v[0]);

	homedir_v = __ns_ldap_getAttr(entry, _PWD_HOMEDIRECTORY);
	if (homedir_v == NULL || homedir_v[0] == NULL || *homedir_v[0] == '\0')
		homedir_v = &NULL_STR;
	else
		str_len += strlen(homedir_v[0]);

	shell_v = __ns_ldap_getAttr(entry, _PWD_LOGINSHELL);
	if (shell_v == NULL || shell_v[0] == NULL || *shell_v[0] == '\0')
		shell_v = &NULL_STR;
	else
		str_len += strlen(shell_v[0]);

	if (str_len >  buflen) {
		nss_result = NSS_STR_PARSE_ERANGE;
		goto result_pwd2str;
	}

	if (argp->buf.result != NULL) {
		be->buflen = str_len + 8;
		be->buffer = malloc(be->buflen);
		if (be->buffer == NULL) {
			nss_result = (int)NSS_STR_PARSE_ERANGE;
			goto result_pwd2str;
		}

		(void) snprintf(be->buffer, be->buflen,
		    "%s:%s:%s:%s:%s:%s:%s",
		    uid_v[0], "x", uidn_v[0], gidn_v[0],
		    gecos_v[0], homedir_v[0], shell_v[0]);
	} else {
		(void) snprintf(argp->buf.buffer, (str_len + 8),
		    "%s:%s:%s:%s:%s:%s:%s",
		    uid_v[0], "x", uidn_v[0], gidn_v[0],
		    gecos_v[0], homedir_v[0], shell_v[0]);
	}

result_pwd2str:

	(void) __ns_ldap_freeResult(&be->result);
	return ((int)nss_result);
}
예제 #6
0
/*
 * _nss_ldap_rpc2str is the data marshaling method for the rpc getXbyY
 * (e.g., getbyname(), getbynumber(), getrpcent()) backend processes.
 * This method is called after a successful ldap search has been performed.
 * This method will parse the ldap search values into the file format.
 * e.g.
 *
 * nfs_acl 100227
 * snmp 100122  na.snmp snmp-cmc snmp-synoptics snmp-unisys snmp-utk
 */
static int
_nss_ldap_rpc2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
{
	uint_t		i;
	int		nss_result;
	int		buflen = 0, len;
	char		*cname = NULL;
	char		*buffer = NULL;
	ns_ldap_result_t	*result = be->result;
	ns_ldap_attr_t	*names;
	char		**rpcnumber;

	if (result == NULL)
		return (NSS_STR_PARSE_PARSE);
	nss_result = NSS_STR_PARSE_SUCCESS;
	(void) memset(argp->buf.buffer, 0, buflen);

	buflen = argp->buf.buflen;
	if (argp->buf.result != NULL) {
		if ((be->buffer = calloc(1, buflen)) == NULL) {
			nss_result = NSS_STR_PARSE_PARSE;
			goto result_rpc2str;
		}
		buffer = be->buffer;
	} else
		buffer = argp->buf.buffer;


	names = __ns_ldap_getAttrStruct(result->entry, _R_NAME);
	if (names == NULL || names->attrvalue == NULL) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_rpc2str;
	}
	/* Get the canonical rpc name */
	cname = __s_api_get_canonical_name(result->entry, names, 1);
	if (cname == NULL || (len = strlen(cname)) < 1) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_rpc2str;
	}
	rpcnumber = __ns_ldap_getAttr(result->entry, _R_NUMBER);
	if (rpcnumber == NULL || rpcnumber[0] == NULL ||
			(len = strlen(rpcnumber[0])) < 1) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_rpc2str;
	}
	len = snprintf(buffer, buflen,  "%s %s", cname, rpcnumber[0]);
	TEST_AND_ADJUST(len, buffer, buflen, result_rpc2str);
	/* Append aliases */
	for (i = 0; i < names->value_count; i++) {
		if (names->attrvalue[i] == NULL) {
			nss_result = NSS_STR_PARSE_PARSE;
			goto result_rpc2str;
		}
		/* Skip the canonical name */
		if (strcasecmp(names->attrvalue[i], cname) != 0) {
			len = snprintf(buffer, buflen,  " %s",
					names->attrvalue[i]);
			TEST_AND_ADJUST(len, buffer, buflen, result_rpc2str);
		}
	}

	/* The front end marshaller doesn't need to copy trailing nulls */
	if (argp->buf.result != NULL)
		be->buflen = strlen(be->buffer);

result_rpc2str:

	(void) __ns_ldap_freeResult(&be->result);
	return (nss_result);
}
예제 #7
0
static nss_status_t
getnetgr_ldap_getent(ldap_backend_ptr be, void *a)
{
	struct nss_getnetgrent_args	*args;
	getnetgrent_cookie_t	*p;
	char			searchfilter[SEARCHFILTERLEN];
	char			userdata[SEARCHFILTERLEN];
	char			name[SEARCHFILTERLEN];
	int			rc;
	void			*cookie = NULL;
	ns_ldap_result_t	*result = NULL;
	ns_ldap_error_t		*error = NULL;
	char			**attrs;
	char			*hostname, *username, *domain;
	char			*buffer;
	nss_status_t		status = NSS_SUCCESS;
	netgroup_name_t		*ng;
	int			ret;

#ifdef	DEBUG
	(void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_getent]\n");
#endif	/* DEBUG */

	args = (struct nss_getnetgrent_args *)a;

	args->status = NSS_NETGR_NO;

	p = (getnetgrent_cookie_t *)be->netgroup_cookie;
	if (p == NULL)
		return ((nss_status_t)NSS_SUCCESS);

	for (;;) {
	    while (p->cookie == NULL) {
		ng = get_next_netgroup(&p->tab);
		if (ng == NULL)	 /* no more */
		    break;

		if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0)
			break;

		ret = snprintf(searchfilter, sizeof (searchfilter),
			_F_SETMEMBER, name);
		if (ret >= sizeof (searchfilter) || ret < 0)
			break;

		ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD,
			name);
		if (ret >= sizeof (userdata) || ret < 0)
			break;

		result = NULL;
		rc = __ns_ldap_firstEntry(_NETGROUP, searchfilter,
			_merge_SSD_filter, netgrent_attrs, NULL, 0, &cookie,
			&result, &error, userdata);
		(void) __ns_ldap_freeError(&error);

		if (rc == NS_LDAP_SUCCESS && result != NULL) {
			p->cookie = cookie;
			p->results = result;
			break;
		}
		(void) __ns_ldap_freeResult(&result);
		(void) __ns_ldap_endEntry(&cookie, &error);
		(void) __ns_ldap_freeError(&error);
	    }
	    if (p->cookie == NULL)
		break;
	    if (p->results == NULL) {
		result = NULL;
		rc = __ns_ldap_nextEntry(p->cookie, &result, &error);
		(void) __ns_ldap_freeError(&error);
		if (rc == NS_LDAP_SUCCESS && result != NULL)
			p->results = result;
		else {
		    (void) __ns_ldap_freeResult(&result);
		    (void) __ns_ldap_endEntry(&p->cookie, &error);
		    (void) __ns_ldap_freeError(&error);
		    p->cookie = NULL;
		}
	    }
	    if (p->results == NULL)
		continue;

	    if (p->entry == NULL)
		p->entry = p->results->entry;

	    if (p->entry == NULL)
		continue;

	    if (p->attrs == NULL) {
		attrs = __ns_ldap_getAttr(p->entry, _N_TRIPLE);
		if (attrs != NULL && *attrs != NULL)
		    p->attrs = attrs;
	    }

	    if (p->attrs != NULL) {
		attrs = p->attrs;
		buffer = args->buffer;

		if (strlcpy(buffer, *attrs, args->buflen) >= args->buflen) {
		    status = NSS_STR_PARSE_ERANGE;
		    break;
		}

		rc = split_triple(buffer, &hostname, &username, &domain);
		attrs++;
		if (attrs != NULL && *attrs != NULL)
		    p->attrs = attrs;
		else
		    p->attrs = NULL;
		if (rc == 0) {
		    args->retp[NSS_NETGR_MACHINE] = hostname;
		    args->retp[NSS_NETGR_USER] = username;
		    args->retp[NSS_NETGR_DOMAIN] = domain;
		    args->status = NSS_NETGR_FOUND;
		    if (p->attrs != NULL)
			break;
		}
	    }

	    if (p->attrs == NULL) {
		rc = add_netgroup_member_entry(p->entry, &p->tab);
		if (rc != 0) {
		    args->status = NSS_NETGR_NO;
		    break;
		}

		p->entry = p->entry->next;
		if (p->entry == NULL)
		    (void) __ns_ldap_freeResult(&p->results);
		if (args->status == NSS_NETGR_FOUND)
		    break;
	    }
	}

	return (status);
}
예제 #8
0
static int
match_triple_entry(struct nss_innetgr_args *ia, const ns_ldap_entry_t *entry)
{
	int	ndomains;
	char	**pdomains;
	int	nhost;
	char	**phost;
	int	nusers;
	char	**pusers;
	char	**attr;
	char	triple[MAX_TRIPLE_LEN];
	char	*tuser, *thost, *tdomain;
	int	i;
	char	*current, *limit;
	int	pulen, phlen;
	char	*pusers0, *phost0;

	nhost = ia->arg[NSS_NETGR_MACHINE].argc;
	phost = (char **)ia->arg[NSS_NETGR_MACHINE].argv;
	if (phost == NULL || *phost == NULL) {
		nhost = 0;
	} else {
		phost0 = phost[0];
		phlen = strlen(phost0);
	}
	nusers = ia->arg[NSS_NETGR_USER].argc;
	pusers = (char **)ia->arg[NSS_NETGR_USER].argv;
	if (pusers == NULL || *pusers == NULL) {
		nusers = 0;
	} else {
		pusers0 = pusers[0];
		pulen = strlen(pusers0);
	}
	ndomains = ia->arg[NSS_NETGR_DOMAIN].argc;
	pdomains = (char **)ia->arg[NSS_NETGR_DOMAIN].argv;
	if (pdomains == NULL || *pdomains == NULL)
		ndomains = 0;

	attr = __ns_ldap_getAttr(entry, _N_TRIPLE);
	if (attr == NULL || *attr == NULL)
		return (0);

	/* Special cases for speedup */
	if (nusers == 1 && nhost == 0 && ndomains == 0) {
		/* Special case for finding a single user in a netgroup */
		for (; *attr; attr++) {
			/* jump to first comma and check next character */
			current = *attr;
			if ((current = strchr(current, COMMA)) == NULL)
				continue;
			current++;

			/* skip whitespaces */
			while (isspace(*current))
				current++;

			/* if user part is null, then treat as wildcard */
			if (*current == COMMA)
				return (1);

			/* compare first character */
			if (*pusers0 != *current)
				continue;

			/* limit username to COMMA */
			if ((limit = strchr(current, COMMA)) == NULL)
				continue;
			*limit = '\0';

			/* remove blanks before COMMA */
			if ((limit = strpbrk(current, " \t")) != NULL)
				*limit = '\0';

			/* compare size of username */
			if (pulen != strlen(current)) {
				continue;
			}

			/* do actual compare */
			if (strncmp(pusers0, current, pulen) == 0) {
				return (1);
			} else {
				continue;
			}
		}
	} else if (nusers == 0 && nhost == 1 && ndomains == 0) {
		/* Special case for finding a single host in a netgroup */
		for (; *attr; attr++) {

			/* jump to first character and check */
			current = *attr;
			current++;

			/* skip whitespaces */
			while (isspace(*current))
				current++;

			/* if host part is null, then treat as wildcard */
			if (*current == COMMA)
				return (1);

			/* limit hostname to COMMA */
			if ((limit = strchr(current, COMMA)) == NULL)
				continue;
			*limit = '\0';

			/* remove blanks before COMMA */
			if ((limit = strpbrk(current, " \t")) != NULL)
				*limit = '\0';

			/* compare size of hostname */
			if (phlen != strlen(current)) {
				continue;
			}

			/* do actual compare */
			if (strncasecmp(phost0, current, phlen) == 0) {
				return (1);
			} else {
				continue;
			}
		}
	} else {
		for (; *attr; attr++) {
			if (strlcpy(triple, *attr,
					sizeof (triple)) >= sizeof (triple))
				continue;
			if (split_triple(triple, &thost, &tuser, &tdomain) != 0)
				continue;
			if (thost != NULL && *thost != '\0' && nhost != 0) {
				for (i = 0; i < nhost; i++)
					if (strcasecmp(thost, phost[i]) == 0)
						break;
				if (i == nhost)
				    continue;
			}
			if (tuser != NULL && *tuser != '\0' && nusers != 0) {
				for (i = 0; i < nusers; i++)
					if (strcmp(tuser, pusers[i]) == 0)
						break;
				if (i == nusers)
					continue;
			}
			if (tdomain != NULL && *tdomain != '\0' &&
					ndomains != 0) {
				for (i = 0; i < ndomains; i++)
					if (domcmp(tdomain, pdomains[i]) == 0)
						break;
				if (i == ndomains)
					continue;
			}
			return (1);
		}
	}

	return (0);
}
예제 #9
0
static
idmap_stat
unixname2dn(idmap_nm_handle_t *p, char *unixname, int is_user, char **dn,
    char **winname, char **windomain)
{
	idmap_stat rc = IDMAP_SUCCESS;
	int rc_ns;


	char filter[255];
	static const char *attribs[3];
	ns_ldap_result_t *res;
	ns_ldap_error_t *errorp = NULL;
	char **attrs;


	attribs[0] = p->nldap_winname_attr;
	attribs[1] = "dn";
	attribs[2] = NULL;

	(void) snprintf(filter, sizeof (filter), is_user ? "uid=%s" : "cn=%s",
	    unixname);

	rc_ns = __ns_ldap_list(is_user ? "passwd" : "group",
	    filter, NULL, attribs, NULL, 0, &res, &errorp, NULL, NULL);


	if (rc_ns == NS_LDAP_NOTFOUND) {
		namemap_log(is_user ? gettext("User %s not found.")
		    : gettext("Group %s not found."),  unixname);
		return (IDMAP_ERR_NOTFOUND);
	} else if (rc_ns != NS_LDAP_SUCCESS) {
		char *msg = "Cause unidentified";
		if (errorp != NULL) {
			(void) __ns_ldap_err2str(errorp->status, &msg);
		}
		namemap_log(gettext("Ldap list failed (%s)."), msg);
		return (IDMAP_ERR_ARG);
	}

	if (res == NULL) {
		namemap_log(gettext("User %s not found"), unixname);
		return (IDMAP_ERR_ARG);
	}

	if (winname != NULL && windomain != NULL) {
		attrs = __ns_ldap_getAttr(&res->entry[0],
		    p->nldap_winname_attr);
		if (attrs != NULL && attrs[0] != NULL) {
			rc = split_fqwn(attrs[0], winname, windomain);
		} else {
			*winname = *windomain = NULL;
		}
	}

	if (dn != NULL) {
		attrs = __ns_ldap_getAttr(&res->entry[0], "dn");
		if (attrs == NULL || attrs[0] == NULL) {
			namemap_log(gettext("dn for %s not found"),
			    unixname);
			return (IDMAP_ERR_ARG);
		}
		*dn = strdup(attrs[0]);
	}


	return (rc);

}
예제 #10
0
/*
 * _nss_ldap_networks2str is the data marshaling method for the networks
 * getXbyY * (e.g., getbyname(), getbyaddr(), getnetent() backend processes.
 * This method is called after a successful ldap search has been performed.
 * This method will parse the ldap search values into the file format.
 * e.g.
 *
 * SunRay-ce2	10.34.96.0	SunRay
 *
 */
static int
_nss_ldap_networks2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
{
	uint_t		i;
	int		nss_result;
	int		buflen = 0, len;
	char		**network, *cname = NULL;
	char		*buffer = NULL;
	ns_ldap_result_t	*result = be->result;
	ns_ldap_attr_t	*names;

	if (result == NULL)
		return (NSS_STR_PARSE_PARSE);
	buflen = argp->buf.buflen;

	if (argp->buf.result != NULL) {
		if ((be->buffer = calloc(1, buflen)) == NULL) {
			nss_result = NSS_STR_PARSE_PARSE;
			goto result_net2str;
		}
		buffer = be->buffer;
	} else
		buffer = argp->buf.buffer;

	nss_result = NSS_STR_PARSE_SUCCESS;
	(void) memset(argp->buf.buffer, 0, buflen);

	names = __ns_ldap_getAttrStruct(result->entry,  _N_NAME);
	if (names == NULL || names->attrvalue == NULL) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_net2str;
	}
	/* Get the canonical name */
	cname = __s_api_get_canonical_name(result->entry, names, 1);
	/*
	 * The definition of the object class  "ipNetwork" has a
	 * discrepency between RFC 2307 and 2307bis.
	 * In 2307, "cn" is a MUST attribute. In 2307bis, "cn" is a
	 * MAY attribute.
	 * If "cn" is a MAY attribute, it does not  appear in RDN and can't
	 * be derived from RDN as a canonical "cn" name. In that case, use 1st
	 * "cn" value as the official name.
	 */
	if (cname == NULL)
		/* 2307bis case */
		cname = names->attrvalue[0];
	if (cname == NULL || (len = strlen(cname)) < 1) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_net2str;
	}
	network = __ns_ldap_getAttr(result->entry, _N_NETWORK);
	if (network == NULL || network[0] == NULL ||
			(len = strlen(network[0])) < 1) {
		nss_result = NSS_STR_PARSE_PARSE;
		goto result_net2str;
	}
	len = snprintf(buffer, buflen,  "%s %s", cname, network[0]);
	TEST_AND_ADJUST(len, buffer, buflen, result_net2str);
	/* Append aliases */
	for (i = 0; i < names->value_count; i++) {
		if (names->attrvalue[i] == NULL) {
			nss_result = NSS_STR_PARSE_PARSE;
			goto result_net2str;
		}
		/* Skip the canonical name */
		if (strcasecmp(names->attrvalue[i], cname) != 0) {
			len = snprintf(buffer, buflen,  " %s",
					names->attrvalue[i]);
			TEST_AND_ADJUST(len, buffer, buflen, result_net2str);
		}
	}

	/* The front end marshaller doesn't need to copy trailing nulls */
	if (argp->buf.result != NULL)
		be->buflen = strlen(be->buffer);

result_net2str:

	(void) __ns_ldap_freeResult(&be->result);
	return (nss_result);
}