Skip to content

Commit

Permalink
Add host access control support
Browse files Browse the repository at this point in the history
  • Loading branch information
ossman authored and sgallagher committed Mar 24, 2011
1 parent ff265d1 commit 3612c73
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/config/SSSDConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ class ProviderSubtypeInUse(SSSDConfigException): pass
'ldap_user_shadow_expire' : _('shadowExpire attribute'),
'ldap_user_shadow_flag' : _('shadowFlag attribute'),
'ldap_user_authorized_service' : _('Attribute listing authorized PAM services'),
'ldap_user_authorized_host' : _('Attribute listing authorized server hosts'),
'ldap_user_krb_last_pwd_change' : _('krbLastPwdChange attribute'),
'ldap_user_krb_password_expiration' : _('krbPasswordExpiration attribute'),
'ldap_pwd_attribute' : _('Attribute indicating that server side password policies are active'),
Expand Down
1 change: 1 addition & 0 deletions src/config/etc/sssd.api.d/sssd-ldap.conf
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ ldap_user_shadow_flag = str, None, false
ldap_user_krb_last_pwd_change = str, None, false
ldap_user_krb_password_expiration = str, None, false
ldap_user_authorized_service = str, None, false
ldap_user_authorized_host = str, None, false
ldap_pwd_attribute = str, None, false
ldap_user_ad_account_expires = str, None, false
ldap_user_ad_user_account_control = str, None, false
Expand Down
1 change: 1 addition & 0 deletions src/db/sysdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#define SYSDB_INITGR_EXPIRE "initgrExpireTimestamp"

#define SYSDB_AUTHORIZED_SERVICE "authorizedService"
#define SYSDB_AUTHORIZED_HOST "authorizedHost"

#define SYSDB_NETGROUP_TRIPLE "netgroupTriple"
#define SYSDB_ORIG_NETGROUP_MEMBER "originalMemberNisNetgroup"
Expand Down
24 changes: 24 additions & 0 deletions src/man/sssd-ldap.5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,26 @@
</listitem>
</varlistentry>

<varlistentry>
<term>ldap_user_authorized_host (string)</term>
<listitem>
<para>
If access_provider=ldap and
ldap_access_order=host, SSSD will use the presence
of the host attribute in the user's LDAP entry to
determine access privilege.
</para>
<para>
An explicit deny (!host) is resolved first. Second,
SSSD searches for explicit allow (host) and finally
for allow_all (*).
</para>
<para>
Default: host
</para>
</listitem>
</varlistentry>

<varlistentry>
<term>ldap_group_object_class (string)</term>
<listitem>
Expand Down Expand Up @@ -1248,6 +1268,10 @@ ldap_access_filter = memberOf=cn=allowedusers,ou=Groups,dc=example,dc=com
the authorizedService attribute to determine
access
</para>
<para>
<emphasis>host</emphasis>: use the host attribute
to determine access
</para>
<para>
Default: filter
</para>
Expand Down
3 changes: 2 additions & 1 deletion src/providers/ipa/ipa_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ struct sdap_attr_map ipa_user_map[] = {
{ "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL },
{ "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL},
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }
};

struct sdap_attr_map ipa_group_map[] = {
Expand Down
6 changes: 4 additions & 2 deletions src/providers/ldap/ldap_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ struct sdap_attr_map rfc2307_user_map[] = {
{ "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL },
{ "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL},
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }
};

struct sdap_attr_map rfc2307_group_map[] = {
Expand Down Expand Up @@ -174,7 +175,8 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
{ "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL },
{ "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL},
{ "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}
{ "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL},
{ "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }
};

struct sdap_attr_map rfc2307bis_group_map[] = {
Expand Down
2 changes: 2 additions & 0 deletions src/providers/ldap/ldap_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ int sssm_ldap_access_init(struct be_ctx *bectx,
}
} else if (strcasecmp(order_list[c], LDAP_ACCESS_SERVICE_NAME) == 0) {
access_ctx->access_rule[c] = LDAP_ACCESS_SERVICE;
} else if (strcasecmp(order_list[c], LDAP_ACCESS_HOST_NAME) == 0) {
access_ctx->access_rule[c] = LDAP_ACCESS_HOST;
} else {
DEBUG(1, ("Unexpected access rule name [%s].\n", order_list[c]));
ret = EINVAL;
Expand Down
1 change: 1 addition & 0 deletions src/providers/ldap/sdap.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ enum sdap_user_attrs {
SDAP_AT_AD_ACCOUNT_EXPIRES,
SDAP_AT_AD_USER_ACCOUNT_CONTROL,
SDAP_AT_NS_ACCOUNT_LOCK,
SDAP_AT_AUTHORIZED_HOST,

SDAP_OPTS_USER /* attrs counter */
};
Expand Down
146 changes: 146 additions & 0 deletions src/providers/ldap/sdap_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ static struct tevent_req *sdap_access_service_send(

static void sdap_account_expired_done(struct tevent_req *subreq);

static errno_t sdap_access_host_recv(struct tevent_req *req,
int *pam_status);
static void sdap_access_host_done(struct tevent_req *subreq);

static struct tevent_req *sdap_access_host_send(
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_access_ctx *access_ctx,
struct pam_data *pd,
struct ldb_message *user_entry);

static void sdap_access_done(struct tevent_req *req);
void sdap_pam_access_handler(struct be_req *breq)
{
Expand Down Expand Up @@ -259,6 +270,18 @@ static errno_t select_next_rule(struct tevent_req *req)
tevent_req_set_callback(subreq, sdap_access_service_done, req);
return EOK;

case LDAP_ACCESS_HOST:
subreq = sdap_access_host_send(state, state->ev,
state->access_ctx,
state->pd,
state->user_entry);
if (subreq == NULL) {
DEBUG(1, ("sdap_access_host_send failed.\n"));
return ENOMEM;
}
tevent_req_set_callback(subreq, sdap_access_host_done, req);
return EOK;

default:
DEBUG(1, ("Unexpected access rule type. Access denied.\n"));
}
Expand Down Expand Up @@ -1057,6 +1080,129 @@ static void sdap_access_service_done(struct tevent_req *subreq)
return;
}

struct sdap_access_host_ctx {
int pam_status;
};

static struct tevent_req *sdap_access_host_send(
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_access_ctx *access_ctx,
struct pam_data *pd,
struct ldb_message *user_entry)
{
errno_t ret;
struct tevent_req *req;
struct sdap_access_host_ctx *state;
struct ldb_message_element *el;
unsigned int i;
char *host;
char hostname[HOST_NAME_MAX+1];

req = tevent_req_create(mem_ctx, &state, struct sdap_access_host_ctx);
if (!req) {
return NULL;
}

state->pam_status = PAM_PERM_DENIED;

el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_HOST);
if (!el || el->num_values == 0) {
DEBUG(1, ("Missing hosts. Access denied\n"));
ret = EOK;
goto done;
}

if (gethostname(hostname, sizeof(hostname)) == -1) {
DEBUG(1, ("Unable to get system hostname. Access denied\n"));
ret = EOK;
goto done;
}

/* FIXME: PADL's pam_ldap also calls gethostbyname() on the hostname
* in some attempt to get aliases and/or FQDN for the machine.
* Not sure this is a good idea, but we might want to add it in
* order to be compatible...
*/

for (i = 0; i < el->num_values; i++) {
host = (char *)el->values[i].data;
if (host[0] == '!' &&
strcasecmp(hostname, host+1) == 0) {
/* This host is explicitly denied */
state->pam_status = PAM_PERM_DENIED;
DEBUG(4, ("Access denied by [%s]\n", host));
/* A denial trumps all. Break here */
break;

} else if (strcasecmp(hostname, host) == 0) {
/* This host is explicitly allowed */
state->pam_status = PAM_SUCCESS;
DEBUG(4, ("Access granted for [%s]\n", host));
/* We still need to loop through to make sure
* that it's not also explicitly denied
*/
} else if (strcmp("*", host) == 0) {
/* This user has access to all hosts */
state->pam_status = PAM_SUCCESS;
DEBUG(4, ("Access granted to all hosts\n"));
/* We still need to loop through to make sure
* that it's not also explicitly denied
*/
}
}

if (state->pam_status != PAM_SUCCESS) {
DEBUG(4, ("No matching host rule found\n"));
}

ret = EOK;

done:
if (ret == EOK) {
tevent_req_done(req);
} else {
tevent_req_error(req, ret);
}
tevent_req_post(req, ev);

return req;
}

static errno_t sdap_access_host_recv(struct tevent_req *req,
int *pam_status)
{
struct sdap_access_host_ctx *state =
tevent_req_data(req, struct sdap_access_host_ctx);

TEVENT_REQ_RETURN_ON_ERROR(req);

*pam_status = state->pam_status;

return EOK;
}

static void sdap_access_host_done(struct tevent_req *subreq)
{
errno_t ret;
struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
struct sdap_access_req_ctx *state =
tevent_req_data(req, struct sdap_access_req_ctx);

ret = sdap_access_host_recv(subreq, &state->pam_status);
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(1, ("Error retrieving access check result.\n"));
state->pam_status = PAM_SYSTEM_ERR;
tevent_req_error(req, ret);
return;
}

next_access_rule(req);

return;
}

static errno_t sdap_access_recv(struct tevent_req *req, int *pam_status)
{
struct sdap_access_req_ctx *state =
Expand Down
2 changes: 2 additions & 0 deletions src/providers/ldap/sdap_access.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define LDAP_ACCESS_FILTER_NAME "filter"
#define LDAP_ACCESS_EXPIRE_NAME "expire"
#define LDAP_ACCESS_SERVICE_NAME "authorized_service"
#define LDAP_ACCESS_HOST_NAME "host"

#define LDAP_ACCOUNT_EXPIRE_SHADOW "shadow"
#define LDAP_ACCOUNT_EXPIRE_AD "ad"
Expand All @@ -44,6 +45,7 @@ enum ldap_access_rule {
LDAP_ACCESS_FILTER = 0,
LDAP_ACCESS_EXPIRE,
LDAP_ACCESS_SERVICE,
LDAP_ACCESS_HOST,
LDAP_ACCESS_LAST
};

Expand Down

0 comments on commit 3612c73

Please sign in to comment.