summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/examples/config.ldif50
-rw-r--r--server/examples/sssdproxylocal9
-rw-r--r--server/examples/sssdproxytest9
-rw-r--r--server/examples/sudo6
-rw-r--r--server/providers/data_provider_be.c155
-rw-r--r--server/providers/dp_backend.h44
-rw-r--r--server/providers/ldap_be.c10
-rw-r--r--server/providers/proxy.c73
8 files changed, 275 insertions, 81 deletions
diff --git a/server/examples/config.ldif b/server/examples/config.ldif
index b848e4314..6101f0851 100644
--- a/server/examples/config.ldif
+++ b/server/examples/config.ldif
@@ -15,31 +15,28 @@ activeServices: info
dn: cn=nss,cn=services,cn=config
cn: nss
description: NSS Responder Configuration
-unixSocket: /var/lib/sss/pipes/nss
-command: /usr/libexec/sssd/sssd_nss
+filterGroups: root
+filterGroups: foo@TEST
+filterUsers: root
+filterUsers: bar@TEST
dn: cn=dp,cn=services,cn=config
cn: dp
description: Data Provider Configuration
-command: /usr/libexec/sssd/sssd_dp
dn: cn=monitor,cn=services,cn=config
cn: monitor
description: Monitor Configuration
sbusTimeout: 10
-sbusAddress: unix:path=/var/lib/sss/pipes/private/dbus
servicePingTime: 10
dn: cn=pam,cn=services,cn=config
cn: pam
-command: /usr/libexec/sssd/sssd_pam
description: PAM Responder Configuration
-unixSocket: /var/lib/sss/pipes/pam
dn: cn=info,cn=services,cn=config
cn: info
description: InfoPipe Configuration
-command: ./sbin/sssd_info
dn: cn=domains,cn=config
cn: domains
@@ -48,32 +45,43 @@ description: Domains served by SSSD
dn: cn=LOCAL,cn=domains,cn=config
cn: LOCAL
description: Reserved domain for local configurations
-legacy: FALSE
enumerate: 3
-
-dn: cn=EXAMPLE.COM,cn=domains,cn=config
-cn: EXAMPLE.COM
-description: Example domain served by IPA
-provider: ipa
-server: ipaserver1.example.com
-server: ipabackupserver.example.com
-legacy: FALSE
-enumerate: 0
+minId: 500
+maxId: 999
+legacy: TRUE
+libName: files
+libPath: /lib64/libnss_files.so.2
+magicPrivateGroups: FALSE
+provider: proxy
+auth-module: proxy
+pam-target: sssdproxylocal
dn: cn=TEST,cn=domains,cn=config
cn: TEST
description: TEST Ldap domain
-provider: proxy
-command: ./sbin/sssd_be -d 2 --provider proxy --domain TEST
libName: ldap
libPath: /usr/lib64/libnss_ldap.so.2
legacy: TRUE
-enumerate: 0
+enumerate: 3
+useFullyQualifiedNames: TRUE
+minId: 1000
+provider: proxy
+auth-module: proxy
+pam-target: sssdproxytest
dn: cn=LDAPTEST,cn=domains,cn=config
cn: LDAPTEST
basedn: cn=LDAPTEST,sn=sysdb
-command: ./sbin/sssd_be --provider ldap --domain LDAPTEST
+command: /usr/libexec/sssd/sssd_be --provider ldap --domain LDAPTEST
description: TEST PAM Ldap domain
provider: ldap
userSearchBase: ou=user,dc=my-domain,dc=com
+
+dn: cn=EXAMPLE.COM,cn=domains,cn=config
+cn: EXAMPLE.COM
+description: Example domain served by IPA
+provider: ipa
+server: ipaserver1.example.com
+server: ipabackupserver.example.com
+legacy: FALSE
+enumerate: 0
diff --git a/server/examples/sssdproxylocal b/server/examples/sssdproxylocal
new file mode 100644
index 000000000..1bc47f89c
--- /dev/null
+++ b/server/examples/sssdproxylocal
@@ -0,0 +1,9 @@
+#%PAM-1.0
+auth sufficient pam_unix.so
+auth requisite pam_succeed_if.so uid >= 500 quiet
+auth required pam_deny.so
+
+account required pam_unix.so
+account sufficient pam_succeed_if.so uid < 500 quiet
+account required pam_permit.so
+
diff --git a/server/examples/sssdproxytest b/server/examples/sssdproxytest
new file mode 100644
index 000000000..9c5cb4ad6
--- /dev/null
+++ b/server/examples/sssdproxytest
@@ -0,0 +1,9 @@
+#%PAM-1.0
+auth sufficient pam_ldap.so debug
+auth requisite pam_succeed_if.so uid >= 1000 quiet
+auth required pam_deny.so
+
+account required pam_ldap.so debug
+account sufficient pam_succeed_if.so uid < 1000 quiet
+account required pam_permit.so
+
diff --git a/server/examples/sudo b/server/examples/sudo
new file mode 100644
index 000000000..4af91ba68
--- /dev/null
+++ b/server/examples/sudo
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth required pam_sss.so
+account required pam_sss.so
+password required pam_sss.so
+session optional pam_keyinit.so revoke
+session required pam_limits.so
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 4e99f5628..61844bbe0 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -49,8 +49,6 @@
#define BE_CONF_ENTRY "config/domains/%s"
-typedef int (*be_init_fn_t)(TALLOC_CTX *, struct be_mod_ops **, void **);
-
static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn);
static int service_pong(DBusMessage *message, struct sbus_conn_ctx *sconn);
@@ -305,7 +303,7 @@ static int be_check_online(DBusMessage *message, struct sbus_conn_ctx *sconn)
be_req->req_data = req;
- ret = be_file_request(ctx, ctx->ops->check_online, be_req);
+ ret = be_file_request(ctx, ctx->id_ops->check_online, be_req);
if (ret != EOK) {
online = MOD_OFFLINE;
err_maj = DP_ERR_FATAL;
@@ -482,7 +480,7 @@ static int be_get_account_info(DBusMessage *message, struct sbus_conn_ctx *sconn
be_req->req_data = req;
- ret = be_file_request(ctx, ctx->ops->get_account_info, be_req);
+ ret = be_file_request(ctx, ctx->id_ops->get_account_info, be_req);
if (ret != EOK) {
err_maj = DP_ERR_FATAL;
err_min = ret;
@@ -588,7 +586,7 @@ static int be_pam_handler(DBusMessage *message, struct sbus_conn_ctx *sconn)
be_req->pvt = reply;
be_req->req_data = pd;
- ret = be_file_request(ctx, ctx->ops->pam_handler, be_req);
+ ret = be_file_request(ctx, ctx->auth_ops->pam_handler, be_req);
if (ret != EOK) {
pam_status = PAM_SYSTEM_ERR;
goto done;
@@ -698,8 +696,7 @@ static int be_cli_init(struct be_ctx *ctx)
}
static int be_finalize(struct be_ctx *ctx);
-static void be_shutdown(struct be_req *req, int status,
- const char *errstr);
+static void be_shutdown(struct be_req *req, int status, const char *errstr);
static void be_cli_reconnect_init(struct sbus_conn_ctx *sconn, int status, void *pvt)
{
@@ -730,37 +727,76 @@ static void be_cli_reconnect_init(struct sbus_conn_ctx *sconn, int status, void
/* Kill the backend and let the monitor restart it */
ret = be_finalize(be_ctx);
if (ret != EOK) {
- DEBUG(0, ("Finalizing back-end failed with error [%d] [%s]", ret, strerror(ret)));
+ DEBUG(0, ("Finalizing back-end failed with error [%d] [%s]\n",
+ ret, strerror(ret)));
be_shutdown(NULL, ret, NULL);
}
}
-static void be_shutdown(struct be_req *req, int status,
- const char *errstr)
+static void be_shutdown(struct be_req *req, int status, const char *errstr)
{
/* Nothing left to do but exit() */
if (status == EOK)
exit(0);
/* Something went wrong in finalize */
+ DEBUG(0, ("Finalizing auth module failed with error [%d] [%s]\n",
+ status, errstr ? : strerror(status)));
+
exit(1);
}
-static int be_finalize(struct be_ctx *ctx)
+static void be_id_shutdown(struct be_req *req, int status, const char *errstr)
{
+ struct be_req *shutdown_req;
+ struct be_ctx *ctx;
int ret;
- struct be_req *shutdown_req = talloc_zero(ctx, struct be_req);
+
+ if (status != EOK) {
+ /* Something went wrong in finalize */
+ DEBUG(0, ("Finalizing auth module failed with error [%d] [%s]\n",
+ status, errstr ? : strerror(status)));
+ }
+
+ ctx = req->be_ctx;
+
+ /* Now shutdown the id module too */
+ shutdown_req = talloc_zero(ctx, struct be_req);
if (!shutdown_req) {
ret = ENOMEM;
goto fail;
}
shutdown_req->be_ctx = ctx;
- shutdown_req->fn = be_shutdown;
+ shutdown_req->fn = be_id_shutdown;
+
+ shutdown_req->pvt = ctx->pvt_id_data;
+
+ ret = be_file_request(ctx, ctx->id_ops->finalize, shutdown_req);
+ if (ret == EOK)
+ return;
+
+fail:
+ /* If we got here, we couldn't shut down cleanly. */
+ be_shutdown(NULL, ret, NULL);
+}
+
+static int be_finalize(struct be_ctx *ctx)
+{
+ struct be_req *shutdown_req;
+ int ret;
+
+ shutdown_req = talloc_zero(ctx, struct be_req);
+ if (!shutdown_req) {
+ ret = ENOMEM;
+ goto fail;
+ }
- shutdown_req->pvt = ctx->pvt_data;
+ shutdown_req->be_ctx = ctx;
+ shutdown_req->fn = be_id_shutdown;
+ shutdown_req->pvt = ctx->pvt_auth_data;
- ret = be_file_request(ctx, ctx->ops->finalize, shutdown_req);
+ ret = be_file_request(ctx, ctx->auth_ops->finalize, shutdown_req);
if (ret == EOK) return EOK;
fail:
@@ -769,13 +805,13 @@ fail:
return ret;
}
-static int load_backend(struct be_ctx *ctx)
+static int load_id_backend(struct be_ctx *ctx)
{
TALLOC_CTX *tmp_ctx;
char *path;
void *handle;
char *mod_init_fn_name;
- be_init_fn_t mod_init_fn;
+ be_id_init_fn_t mod_init_fn;
int ret;
tmp_ctx = talloc_new(ctx);
@@ -804,7 +840,7 @@ static int load_backend(struct be_ctx *ctx)
goto done;
}
- mod_init_fn = (be_init_fn_t)dlsym(handle, mod_init_fn_name);
+ mod_init_fn = (be_id_init_fn_t)dlsym(handle, mod_init_fn_name);
if (!mod_init_fn) {
DEBUG(0, ("Unable to load init fn from module %s, error: %s\n",
ctx->name, dlerror()));
@@ -812,7 +848,7 @@ static int load_backend(struct be_ctx *ctx)
goto done;
}
- ret = mod_init_fn(ctx, &ctx->ops, &ctx->pvt_data);
+ ret = mod_init_fn(ctx, &ctx->id_ops, &ctx->pvt_id_data);
if (ret != EOK) {
DEBUG(0, ("Error (%d) in module (%s) initialization!\n",
ret, ctx->name));
@@ -826,6 +862,75 @@ done:
return ret;
}
+static int load_auth_backend(struct be_ctx *ctx)
+{
+ TALLOC_CTX *tmp_ctx;
+ char *mod_name;
+ char *path;
+ void *handle;
+ char *mod_init_fn_name;
+ be_auth_init_fn_t mod_init_fn;
+ int ret;
+
+ tmp_ctx = talloc_new(ctx);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ ret = confdb_get_string(ctx->cdb, tmp_ctx, ctx->conf_path,
+ "auth-module", NULL, &mod_name);
+ if (ret != EOK) {
+ ret = EFAULT;
+ goto done;
+ }
+ if (!mod_name) {
+ ret = ENOENT;
+ goto done;
+ }
+
+ path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so",
+ DATA_PROVIDER_PLUGINS_PATH, mod_name);
+ if (!path) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ handle = dlopen(path, RTLD_NOW);
+ if (!handle) {
+ DEBUG(0, ("Unable to load %s module with path (%s), error: %s\n",
+ mod_name, path, dlerror()));
+ ret = ELIBACC;
+ goto done;
+ }
+
+ mod_init_fn_name = talloc_asprintf(tmp_ctx, "sssm_%s_auth_init", mod_name);
+ if (!mod_init_fn_name) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ mod_init_fn = (be_auth_init_fn_t)dlsym(handle, mod_init_fn_name);
+ if (!mod_init_fn) {
+ DEBUG(0, ("Unable to load init fn from module %s, error: %s\n",
+ mod_name, dlerror()));
+ ret = ELIBBAD;
+ goto done;
+ }
+
+ ret = mod_init_fn(ctx, &ctx->auth_ops, &ctx->pvt_auth_data);
+ if (ret != EOK) {
+ DEBUG(0, ("Error (%d) in module (%s) initialization!\n",
+ ret, mod_name));
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int be_process_init(TALLOC_CTX *mem_ctx,
const char *be_name,
const char *be_domain,
@@ -869,12 +974,22 @@ int be_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = load_backend(ctx);
+ ret = load_id_backend(ctx);
if (ret != EOK) {
DEBUG(0, ("fatal error initializing data providers\n"));
return ret;
}
+ ret = load_auth_backend(ctx);
+ if (ret != EOK) {
+ if (ret != ENOENT) {
+ DEBUG(0, ("fatal error initializing data providers\n"));
+ return ret;
+ }
+ DEBUG(1, ("No authentication module provided for [%s] !!\n",
+ be_domain));
+ }
+
return EOK;
}
diff --git a/server/providers/dp_backend.h b/server/providers/dp_backend.h
index 12cfb3a51..2d1cd83e9 100644
--- a/server/providers/dp_backend.h
+++ b/server/providers/dp_backend.h
@@ -27,10 +27,15 @@
#include "responder/pam/pamsrv.h"
struct be_ctx;
+struct be_id_ops;
+struct be_auth_ops;
+struct be_req;
+typedef int (*be_id_init_fn_t)(TALLOC_CTX *, struct be_id_ops **, void **);
+typedef int (*be_auth_init_fn_t)(TALLOC_CTX *, struct be_auth_ops **, void **);
typedef void (*be_shutdown_fn)(void *);
-
-struct be_mod_ops;
+typedef void (*be_req_fn_t)(struct be_req *);
+typedef void (*be_async_callback_t)(struct be_req *, int, const char *);
struct be_ctx {
struct tevent_context *ev;
@@ -42,14 +47,24 @@ struct be_ctx {
const char *domain;
const char *identity;
const char *conf_path;
- struct be_mod_ops *ops;
- void *pvt_data;
- be_shutdown_fn shutdown;
+
+ struct be_id_ops *id_ops;
+ void *pvt_id_data;
+
+ struct be_auth_ops *auth_ops;
+ void *pvt_auth_data;
};
-struct be_req;
+struct be_id_ops {
+ be_req_fn_t check_online;
+ be_req_fn_t get_account_info;
+ be_req_fn_t finalize;
+};
-typedef void (*be_async_callback_t)(struct be_req *, int, const char *);
+struct be_auth_ops {
+ be_req_fn_t pam_handler;
+ be_req_fn_t finalize;
+};
struct be_req {
struct be_ctx *be_ctx;
@@ -70,19 +85,4 @@ struct be_online_req {
int online;
};
-struct be_pam_handler {
- int pam_status;
- const char *domain;
- struct pam_data *pd;
-};
-
-typedef void (*be_req_fn_t)(struct be_req *);
-
-struct be_mod_ops {
- be_req_fn_t check_online;
- be_req_fn_t get_account_info;
- be_req_fn_t pam_handler;
- be_req_fn_t finalize;
-};
-
#endif /* __DP_BACKEND_H___ */
diff --git a/server/providers/ldap_be.c b/server/providers/ldap_be.c
index 9fe256404..2c075bd06 100644
--- a/server/providers/ldap_be.c
+++ b/server/providers/ldap_be.c
@@ -592,7 +592,7 @@ static void sdap_pam_handler(struct be_req *req)
pd = talloc_get_type(req->req_data, struct pam_data);
- sdap_ctx = talloc_get_type(req->be_ctx->pvt_data, struct sdap_ctx);
+ sdap_ctx = talloc_get_type(req->be_ctx->pvt_auth_data, struct sdap_ctx);
lr = talloc(req, struct sdap_req);
@@ -628,15 +628,15 @@ static void sdap_shutdown(struct be_req *req)
req->fn(req, EOK, NULL);
}
-struct be_mod_ops sdap_mod_ops = {
- .check_online = NULL,
- .get_account_info = NULL,
+struct be_auth_ops sdap_mod_ops = {
.pam_handler = sdap_pam_handler,
.finalize = sdap_shutdown
};
-int sssm_ldap_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_data)
+int sssm_ldap_auth_init(struct be_ctx *bectx,
+ struct be_auth_ops **ops,
+ void **pvt_data)
{
struct sdap_ctx *ctx;
char *ldap_uri;
diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index c87b482f0..1b4a83002 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -61,6 +61,10 @@ struct proxy_ctx {
struct proxy_nss_ops ops;
};
+struct proxy_auth_ctx {
+ char *pam_target;
+};
+
struct authtok_conv {
char *authtok;
char *oldauthtok;
@@ -84,7 +88,7 @@ static int proxy_internal_conv(int num_msg, const struct pam_message **msgm,
for (i=0; i < num_msg; i++) {
switch( msgm[i]->msg_style ) {
case PAM_PROMPT_ECHO_OFF:
- DEBUG(4, ("Conversation message: %s.\n", msgm[i]->msg));
+ DEBUG(4, ("Conversation message: [%s]\n", msgm[i]->msg));
reply[i].resp_retcode = 0;
reply[i].resp = strdup(auth_data->authtok);
break;
@@ -112,14 +116,16 @@ static void proxy_pam_handler(struct be_req *req) {
struct authtok_conv *auth_data;
struct pam_conv conv;
struct pam_data *pd;
+ struct proxy_auth_ctx *ctx;;
+ ctx = talloc_get_type(req->be_ctx->pvt_auth_data, struct proxy_auth_ctx);
pd = talloc_get_type(req->req_data, struct pam_data);
conv.conv=proxy_internal_conv;
auth_data = talloc_zero(req->be_ctx, struct authtok_conv);
conv.appdata_ptr=auth_data;
- ret = pam_start("sssd_be_test", pd->user, &conv, &pamh);
+ ret = pam_start(ctx->pam_target, pd->user, &conv, &pamh);
if (ret == PAM_SUCCESS) {
DEBUG(1, ("Pam transaction started.\n"));
pam_set_item(pamh, PAM_TTY, pd->tty);
@@ -279,7 +285,7 @@ static void get_pw_name(struct be_req *req, char *name)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -340,7 +346,7 @@ static void get_pw_uid(struct be_req *req, uid_t uid)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -478,7 +484,7 @@ static void enum_users(struct be_req *req)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -551,7 +557,7 @@ static void get_gr_name(struct be_req *req, char *name)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -611,7 +617,7 @@ static void get_gr_gid(struct be_req *req, gid_t gid)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -741,7 +747,7 @@ static void enum_groups(struct be_req *req)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -920,7 +926,7 @@ static void get_initgr_user(struct be_req *req, char *name)
struct proxy_data *data;
int ret;
- ctx = talloc_get_type(req->be_ctx->pvt_data, struct proxy_ctx);
+ ctx = talloc_get_type(req->be_ctx->pvt_id_data, struct proxy_ctx);
data = talloc_zero(req, struct proxy_data);
if (!data)
@@ -1109,13 +1115,23 @@ static void proxy_shutdown(struct be_req *req)
req->fn(req, EOK, NULL);
}
-struct be_mod_ops proxy_mod_ops = {
+static void proxy_auth_shutdown(struct be_req *req)
+{
+ talloc_free(req->be_ctx->pvt_auth_data);
+ req->fn(req, EOK, NULL);
+}
+
+struct be_id_ops proxy_id_ops = {
.check_online = proxy_check_online,
.get_account_info = proxy_get_account_info,
- .pam_handler = proxy_pam_handler,
.finalize = proxy_shutdown
};
+struct be_auth_ops proxy_auth_ops = {
+ .pam_handler = proxy_pam_handler,
+ .finalize = proxy_auth_shutdown
+};
+
static void *proxy_dlsym(void *handle, const char *functemp, char *libname)
{
char *funcname;
@@ -1130,7 +1146,8 @@ static void *proxy_dlsym(void *handle, const char *functemp, char *libname)
return funcptr;
}
-int sssm_proxy_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_data)
+int sssm_proxy_init(struct be_ctx *bectx,
+ struct be_id_ops **ops, void **pvt_data)
{
struct proxy_ctx *ctx;
char *libname;
@@ -1240,7 +1257,7 @@ int sssm_proxy_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_da
"full groups enumeration!\n", libname));
}
- *ops = &proxy_mod_ops;
+ *ops = &proxy_id_ops;
*pvt_data = ctx;
ret = EOK;
@@ -1250,3 +1267,33 @@ done:
}
return ret;
}
+
+int sssm_proxy_auth_init(struct be_ctx *bectx,
+ struct be_auth_ops **ops, void **pvt_data)
+{
+ struct proxy_auth_ctx *ctx;
+ int ret;
+
+ ctx = talloc(bectx, struct proxy_auth_ctx);
+ if (!ctx) return ENOMEM;
+
+ ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
+ "pam-target", NULL, &ctx->pam_target);
+ if (ret != EOK) goto done;
+ if (!ctx->pam_target) {
+ ctx->pam_target = talloc_strdup(ctx, "sssd_pam_proxy_default");
+ if (!ctx->pam_target) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ *ops = &proxy_auth_ops;
+ *pvt_data = ctx;
+
+done:
+ if (ret != EOK) {
+ talloc_free(ctx);
+ }
+ return ret;
+}