|
Packit |
6bd9ab |
/*
|
|
Packit |
6bd9ab |
attmap.c - attribute mapping values and functions
|
|
Packit |
6bd9ab |
This file is part of the nss-pam-ldapd library.
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
Copyright (C) 2007-2014 Arthur de Jong
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
This library is free software; you can redistribute it and/or
|
|
Packit |
6bd9ab |
modify it under the terms of the GNU Lesser General Public
|
|
Packit |
6bd9ab |
License as published by the Free Software Foundation; either
|
|
Packit |
6bd9ab |
version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
This library is distributed in the hope that it will be useful,
|
|
Packit |
6bd9ab |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
6bd9ab |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
6bd9ab |
Lesser General Public License for more details.
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
6bd9ab |
License along with this library; if not, write to the Free Software
|
|
Packit |
6bd9ab |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit |
6bd9ab |
02110-1301 USA
|
|
Packit |
6bd9ab |
*/
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
#include "config.h"
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
#include <stdlib.h>
|
|
Packit |
6bd9ab |
#include <strings.h>
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
#include "attmap.h"
|
|
Packit |
6bd9ab |
#include "log.h"
|
|
Packit |
6bd9ab |
#include "common/expr.h"
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
/* these are the bases that are defined per database */
|
|
Packit |
6bd9ab |
extern const char *alias_bases[];
|
|
Packit |
6bd9ab |
extern const char *ether_bases[];
|
|
Packit |
6bd9ab |
extern const char *group_bases[];
|
|
Packit |
6bd9ab |
extern const char *host_bases[];
|
|
Packit |
6bd9ab |
extern const char *netgroup_bases[];
|
|
Packit |
6bd9ab |
extern const char *network_bases[];
|
|
Packit |
6bd9ab |
extern const char *passwd_bases[];
|
|
Packit |
6bd9ab |
extern const char *protocol_bases[];
|
|
Packit |
6bd9ab |
extern const char *rpc_bases[];
|
|
Packit |
6bd9ab |
extern const char *service_bases[];
|
|
Packit |
6bd9ab |
extern const char *shadow_bases[];
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
const char **base_get_var(enum ldap_map_selector map)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
switch (map)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
case LM_ALIASES: return alias_bases;
|
|
Packit |
6bd9ab |
case LM_ETHERS: return ether_bases;
|
|
Packit |
6bd9ab |
case LM_GROUP: return group_bases;
|
|
Packit |
6bd9ab |
case LM_HOSTS: return host_bases;
|
|
Packit |
6bd9ab |
case LM_NETGROUP: return netgroup_bases;
|
|
Packit |
6bd9ab |
case LM_NETWORKS: return network_bases;
|
|
Packit |
6bd9ab |
case LM_PASSWD: return passwd_bases;
|
|
Packit |
6bd9ab |
case LM_PROTOCOLS: return protocol_bases;
|
|
Packit |
6bd9ab |
case LM_RPC: return rpc_bases;
|
|
Packit |
6bd9ab |
case LM_SERVICES: return service_bases;
|
|
Packit |
6bd9ab |
case LM_SHADOW: return shadow_bases;
|
|
Packit |
6bd9ab |
case LM_NFSIDMAP:
|
|
Packit |
6bd9ab |
case LM_NONE:
|
|
Packit |
6bd9ab |
default: return NULL;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
/* these are the scopes that are defined per database */
|
|
Packit |
6bd9ab |
extern int alias_scope;
|
|
Packit |
6bd9ab |
extern int ether_scope;
|
|
Packit |
6bd9ab |
extern int group_scope;
|
|
Packit |
6bd9ab |
extern int host_scope;
|
|
Packit |
6bd9ab |
extern int netgroup_scope;
|
|
Packit |
6bd9ab |
extern int network_scope;
|
|
Packit |
6bd9ab |
extern int passwd_scope;
|
|
Packit |
6bd9ab |
extern int protocol_scope;
|
|
Packit |
6bd9ab |
extern int rpc_scope;
|
|
Packit |
6bd9ab |
extern int service_scope;
|
|
Packit |
6bd9ab |
extern int shadow_scope;
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
int *scope_get_var(enum ldap_map_selector map)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
switch (map)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
case LM_ALIASES: return &alias_scope;
|
|
Packit |
6bd9ab |
case LM_ETHERS: return ðer_scope;
|
|
Packit |
6bd9ab |
case LM_GROUP: return &group_scope;
|
|
Packit |
6bd9ab |
case LM_HOSTS: return &host_scope;
|
|
Packit |
6bd9ab |
case LM_NETGROUP: return &netgroup_scope;
|
|
Packit |
6bd9ab |
case LM_NETWORKS: return &network_scope;
|
|
Packit |
6bd9ab |
case LM_PASSWD: return &passwd_scope;
|
|
Packit |
6bd9ab |
case LM_PROTOCOLS: return &protocol_scope;
|
|
Packit |
6bd9ab |
case LM_RPC: return &rpc_scope;
|
|
Packit |
6bd9ab |
case LM_SERVICES: return &service_scope;
|
|
Packit |
6bd9ab |
case LM_SHADOW: return &shadow_scope;
|
|
Packit |
6bd9ab |
case LM_NFSIDMAP:
|
|
Packit |
6bd9ab |
case LM_NONE:
|
|
Packit |
6bd9ab |
default: return NULL;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
/* these are the filters that are defined per database */
|
|
Packit |
6bd9ab |
extern const char *alias_filter;
|
|
Packit |
6bd9ab |
extern const char *ether_filter;
|
|
Packit |
6bd9ab |
extern const char *group_filter;
|
|
Packit |
6bd9ab |
extern const char *host_filter;
|
|
Packit |
6bd9ab |
extern const char *netgroup_filter;
|
|
Packit |
6bd9ab |
extern const char *network_filter;
|
|
Packit |
6bd9ab |
extern const char *passwd_filter;
|
|
Packit |
6bd9ab |
extern const char *protocol_filter;
|
|
Packit |
6bd9ab |
extern const char *rpc_filter;
|
|
Packit |
6bd9ab |
extern const char *service_filter;
|
|
Packit |
6bd9ab |
extern const char *shadow_filter;
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
const char **filter_get_var(enum ldap_map_selector map)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
switch (map)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
case LM_ALIASES: return &alias_filter;
|
|
Packit |
6bd9ab |
case LM_ETHERS: return ðer_filter;
|
|
Packit |
6bd9ab |
case LM_GROUP: return &group_filter;
|
|
Packit |
6bd9ab |
case LM_HOSTS: return &host_filter;
|
|
Packit |
6bd9ab |
case LM_NETGROUP: return &netgroup_filter;
|
|
Packit |
6bd9ab |
case LM_NETWORKS: return &network_filter;
|
|
Packit |
6bd9ab |
case LM_PASSWD: return &passwd_filter;
|
|
Packit |
6bd9ab |
case LM_PROTOCOLS: return &protocol_filter;
|
|
Packit |
6bd9ab |
case LM_RPC: return &rpc_filter;
|
|
Packit |
6bd9ab |
case LM_SERVICES: return &service_filter;
|
|
Packit |
6bd9ab |
case LM_SHADOW: return &shadow_filter;
|
|
Packit |
6bd9ab |
case LM_NFSIDMAP:
|
|
Packit |
6bd9ab |
case LM_NONE:
|
|
Packit |
6bd9ab |
default: return NULL;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
const char **attmap_get_var(enum ldap_map_selector map, const char *name)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (map == LM_ALIASES)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_alias_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "rfc822MailMember") == 0) return &attmap_alias_rfc822MailMember;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_ETHERS)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_ether_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "macAddress") == 0) return &attmap_ether_macAddress;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_GROUP)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_group_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "userPassword") == 0) return &attmap_group_userPassword;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "gidNumber") == 0) return &attmap_group_gidNumber;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "memberUid") == 0) return &attmap_group_memberUid;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "member") == 0) return &attmap_group_member;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_HOSTS)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_host_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "ipHostNumber") == 0) return &attmap_host_ipHostNumber;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_NETGROUP)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_netgroup_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "nisNetgroupTriple") == 0) return &attmap_netgroup_nisNetgroupTriple;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "memberNisNetgroup") == 0) return &attmap_netgroup_memberNisNetgroup;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_NETWORKS)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_network_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "ipNetworkNumber") == 0) return &attmap_network_ipNetworkNumber;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_PASSWD)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "uid") == 0) return &attmap_passwd_uid;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "userPassword") == 0) return &attmap_passwd_userPassword;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "uidNumber") == 0) return &attmap_passwd_uidNumber;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "gidNumber") == 0) return &attmap_passwd_gidNumber;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "gecos") == 0) return &attmap_passwd_gecos;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "homeDirectory") == 0) return &attmap_passwd_homeDirectory;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "loginShell") == 0) return &attmap_passwd_loginShell;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_PROTOCOLS)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_protocol_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "ipProtocolNumber") == 0) return &attmap_protocol_ipProtocolNumber;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_RPC)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_rpc_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "oncRpcNumber") == 0) return &attmap_rpc_oncRpcNumber;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_SERVICES)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "cn") == 0) return &attmap_service_cn;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "ipServicePort") == 0) return &attmap_service_ipServicePort;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "ipServiceProtocol") == 0) return &attmap_service_ipServiceProtocol;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
else if (map == LM_SHADOW)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "uid") == 0) return &attmap_shadow_uid;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "userPassword") == 0) return &attmap_shadow_userPassword;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "shadowLastChange") == 0) return &attmap_shadow_shadowLastChange;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "shadowMin") == 0) return &attmap_shadow_shadowMin;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "shadowMax") == 0) return &attmap_shadow_shadowMax;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "shadowWarning") == 0) return &attmap_shadow_shadowWarning;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "shadowInactive") == 0) return &attmap_shadow_shadowInactive;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "shadowExpire") == 0) return &attmap_shadow_shadowExpire;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "shadowFlag") == 0) return &attmap_shadow_shadowFlag;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
return NULL;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
const char *attmap_set_mapping(const char **var, const char *value)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
/* check if we are setting an expression */
|
|
Packit |
6bd9ab |
if (value[0] == '"')
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
/* these attributes may contain an expression
|
|
Packit |
6bd9ab |
(note that this needs to match the functionality in the specific
|
|
Packit |
6bd9ab |
lookup module) */
|
|
Packit |
6bd9ab |
if ((var != &attmap_group_userPassword) &&
|
|
Packit |
6bd9ab |
(var != &attmap_group_member) &&
|
|
Packit |
6bd9ab |
(var != &attmap_passwd_userPassword) &&
|
|
Packit |
6bd9ab |
(var != &attmap_passwd_gidNumber) &&
|
|
Packit |
6bd9ab |
(var != &attmap_passwd_gecos) &&
|
|
Packit |
6bd9ab |
(var != &attmap_passwd_homeDirectory) &&
|
|
Packit |
6bd9ab |
(var != &attmap_passwd_loginShell) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_userPassword) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_shadowLastChange) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_shadowMin) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_shadowMax) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_shadowWarning) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_shadowInactive) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_shadowExpire) &&
|
|
Packit |
6bd9ab |
(var != &attmap_shadow_shadowFlag))
|
|
Packit |
6bd9ab |
return NULL;
|
|
Packit |
6bd9ab |
/* the member attribute may only be set to an empty string */
|
|
Packit |
6bd9ab |
if ((var == &attmap_group_member) && (strcmp(value, "\"\"") != 0))
|
|
Packit |
6bd9ab |
return NULL;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
/* check if the value will be changed */
|
|
Packit |
6bd9ab |
if ((*var == NULL) || (strcmp(*var, value) != 0))
|
|
Packit |
6bd9ab |
*var = strdup(value);
|
|
Packit |
6bd9ab |
return *var;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
static const char *entry_expand(const char *name, void *expander_attr)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
MYLDAP_ENTRY *entry = (MYLDAP_ENTRY *)expander_attr;
|
|
Packit |
6bd9ab |
const char **values;
|
|
Packit |
6bd9ab |
if (strcasecmp(name, "dn") == 0)
|
|
Packit |
6bd9ab |
return myldap_get_dn(entry);
|
|
Packit |
6bd9ab |
values = myldap_get_values(entry, name);
|
|
Packit |
6bd9ab |
if (values == NULL)
|
|
Packit |
6bd9ab |
return "";
|
|
Packit |
6bd9ab |
/* TODO: handle userPassword attribute specially */
|
|
Packit |
6bd9ab |
if ((values[0] != NULL) && (values[1] != NULL))
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
log_log(LOG_WARNING, "%s: %s: multiple values",
|
|
Packit |
6bd9ab |
myldap_get_dn(entry), name);
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
return values[0];
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
const char *attmap_get_value(MYLDAP_ENTRY *entry, const char *attr,
|
|
Packit |
6bd9ab |
char *buffer, size_t buflen)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
const char **values;
|
|
Packit |
6bd9ab |
/* check and clear buffer */
|
|
Packit |
6bd9ab |
if ((buffer == NULL) || (buflen <= 0))
|
|
Packit |
6bd9ab |
return NULL;
|
|
Packit |
6bd9ab |
buffer[0] = '\0';
|
|
Packit |
6bd9ab |
/* for simple values just return the attribute */
|
|
Packit |
6bd9ab |
if (attr[0] != '"')
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
values = myldap_get_values(entry, attr);
|
|
Packit |
6bd9ab |
if ((values == NULL) || (values[0] == NULL))
|
|
Packit |
6bd9ab |
return NULL;
|
|
Packit |
6bd9ab |
if (strlen(values[0]) >= buflen)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
log_log(LOG_ERR, "attmap_get_value(): buffer too small (%lu required)",
|
|
Packit |
6bd9ab |
(unsigned long) strlen(values[0]));
|
|
Packit |
6bd9ab |
return NULL;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
strncpy(buffer, values[0], buflen);
|
|
Packit |
6bd9ab |
buffer[buflen - 1] = '\0';
|
|
Packit |
6bd9ab |
return buffer;
|
|
Packit |
6bd9ab |
/* TODO: maybe warn when multiple values are found */
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
/* we have an expression, try to parse */
|
|
Packit |
6bd9ab |
if ((attr[strlen(attr) - 1] != '"') ||
|
|
Packit |
6bd9ab |
(expr_parse(attr + 1, buffer, buflen, entry_expand, (void *)entry) == NULL))
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
log_log(LOG_ERR, "attribute mapping %s is invalid", attr);
|
|
Packit |
6bd9ab |
buffer[0] = '\0';
|
|
Packit |
6bd9ab |
return NULL;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
/* strip trailing " */
|
|
Packit |
6bd9ab |
if (buffer[strlen(buffer) - 1] == '"')
|
|
Packit |
6bd9ab |
buffer[strlen(buffer) - 1] = '\0';
|
|
Packit |
6bd9ab |
return buffer;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
SET *attmap_add_attributes(SET *set, const char *attr)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (attr[0] != '\"')
|
|
Packit |
6bd9ab |
set_add(set, attr);
|
|
Packit |
6bd9ab |
else
|
|
Packit |
6bd9ab |
expr_vars(attr, set);
|
|
Packit |
6bd9ab |
return set;
|
|
Packit |
6bd9ab |
}
|