diff options
author | Sumit Bose <sbose@redhat.com> | 2009-02-17 15:47:04 +0100 |
---|---|---|
committer | Sumit Bose <sbose@redhat.com> | 2009-02-24 11:34:45 +0100 |
commit | 280fc15bcfafbc805e42aaa3375da48e963d6dbe (patch) | |
tree | 98f2144574474a078c91f4dbced785fb98ef959a | |
parent | e3a4b38b1e42f2611246f9f0e92bbac379388c74 (diff) | |
download | sssd-280fc15bcfafbc805e42aaa3375da48e963d6dbe.tar.gz sssd-280fc15bcfafbc805e42aaa3375da48e963d6dbe.tar.xz sssd-280fc15bcfafbc805e42aaa3375da48e963d6dbe.zip |
some cleanups and core reordering
-rw-r--r-- | BUILD.txt | 20 | ||||
-rw-r--r-- | server/nss/pamsrv.h | 2 | ||||
-rw-r--r-- | server/nss/pamsrv_cmd.c | 39 | ||||
-rw-r--r-- | server/providers/ldap_be.c | 255 | ||||
-rw-r--r-- | server/server.mk | 2 | ||||
-rw-r--r-- | server/util/ssssrv_common.c | 8 | ||||
-rw-r--r-- | server/util/ssssrv_common.h | 8 | ||||
-rw-r--r-- | sss_client/Makefile.in | 13 | ||||
-rw-r--r-- | sss_client/pam_sss.c | 63 | ||||
-rw-r--r-- | sss_client/sss_cli.h | 3 |
10 files changed, 229 insertions, 184 deletions
@@ -19,7 +19,7 @@ I use the following steps to build all pieces. export LD_LIBRARY_PATH=/tmp/foo/lib pushd talloc; ./autogen.sh && ./configure --with-shared-build-dir=/tmp/foo && make shared-build; popd pushd tdb; ./autogen.sh && ./configure --with-shared-build-dir=/tmp/foo && make shared-build; popd -pushd events; ./autogen.sh && ./configure --with-shared-build-dir=/tmp/foo && make shared-build; popd +pushd tevent; ./autogen.sh && ./configure --with-shared-build-dir=/tmp/foo && make shared-build; popd pushd ldb; ./autogen.sh && ./configure --with-shared-build-dir=/tmp/foo && make shared-build; popd pushd server; ./autogen.sh && ./configure --with-shared-build-dir=/tmp/foo && make; popd @@ -32,12 +32,26 @@ export LD_LIBRARY_PATH=/tmp/foo/lib This will start the sssd daemon in interactive mode. -The nss_client doesn't need any dependency nor supports the shared-build option. +The nss and pam client doesn't need any dependency nor supports the +shared-build option. -pushd nss_client; ./autogen.sh && ./configure && make; popd +pushd sss_client; ./autogen.sh && ./configure && make; popd Now you have to copy libnss_sss* into /lib (or /lib64) and add the 'sss' traget to nsswitch.conf passwd database +For pam copy pam_sss.so into /lib/security (or /lib64/security) and add +pam_sss.so to your pam configuration. To use the pam_test_client from +sss_client create the following file: + +/etc/pam.d/sss_test: +auth required pam_sss.so +account required pam_sss.so +password required pam_sss.so +session required pam_sss.so + +Now you can call pam_test_client: +./pam_test_client username@domain + ~~~~~ Simo. diff --git a/server/nss/pamsrv.h b/server/nss/pamsrv.h index ad1fc0dc5..4dbb942f2 100644 --- a/server/nss/pamsrv.h +++ b/server/nss/pamsrv.h @@ -17,8 +17,6 @@ struct pam_data { char *rhost; uint8_t *authtok; uint8_t *newauthtok; -/* FIXME: delete oldauthtok if everything changed to newauthtok */ - char *oldauthtok; }; typedef void (*pam_dp_callback_t)(struct cli_ctx *cctx, int pam_status, char *domain); diff --git a/server/nss/pamsrv_cmd.c b/server/nss/pamsrv_cmd.c index de8d115b9..6a36bb648 100644 --- a/server/nss/pamsrv_cmd.c +++ b/server/nss/pamsrv_cmd.c @@ -22,14 +22,9 @@ static int pam_parse_in_data(uint8_t *body, size_t blen, struct pam_data *pd) { int last=blen-1; char *delim; - if (body[last] != '\0') { - return EINVAL; - } - start = end = 0; while ( end < last && body[end++]!='\0'); pd->user = (char *) &body[start]; - DEBUG(4, ("%d %d %d\n", start, end, blen)); delim = strchr(pd->user, SSS_DOMAIN_DELIM); if (delim != NULL ) { @@ -42,33 +37,18 @@ static int pam_parse_in_data(uint8_t *body, size_t blen, struct pam_data *pd) { start = end; while ( end < last && body[end++]!='\0'); pd->service = (char *) &body[start]; - DEBUG(4, ("%d %d %d\n", start, end, blen)); start = end; while ( end < last && body[end++]!='\0'); pd->tty = (char *) &body[start]; - DEBUG(4, ("%d %d %d\n", start, end, blen)); start = end; while ( end < last && body[end++]!='\0'); pd->ruser = (char *) &body[start]; - DEBUG(4, ("%d %d %d\n", start, end, blen)); start = end; while ( end < last && body[end++]!='\0'); pd->rhost = (char *) &body[start]; - DEBUG(4, ("%d %d %d\n", start, end, blen)); -/* - start = end; - while ( end < last && body[end++]!='\0'); - pd->authtok = (char *) &body[start]; - DEBUG(4, ("%d %d %d\n", start, end, blen)); - - start = end; - while ( end < last && body[end++]!='\0'); - pd->oldauthtok = (char *) &body[start]; - DEBUG(4, ("%d %d %d\n", start, end, blen)); -*/ start = end; pd->authtok_type = (int) body[start]; @@ -79,7 +59,6 @@ static int pam_parse_in_data(uint8_t *body, size_t blen, struct pam_data *pd) { if ( end <= blen ) { pd->authtok = (uint8_t *) &body[start]; } else { - DEBUG(4, ("%d %d %d\n", start, end, blen)); DEBUG(1, ("Invalid authtok size: %d\n", pd->authtok_size)); return EINVAL; } @@ -94,18 +73,14 @@ static int pam_parse_in_data(uint8_t *body, size_t blen, struct pam_data *pd) { if ( end <= blen ) { pd->newauthtok = (uint8_t *) &body[start]; } else { - DEBUG(4, ("%d %d %d\n", start, end, blen)); DEBUG(1, ("Invalid newauthtok size: %d\n", pd->newauthtok_size)); return EINVAL; } - DEBUG(4, ("%d %d %d\n", start, end, blen)); - - pam_print_data(pd); return EOK; -} +} static void pam_reply(struct cli_ctx *cctx, int pam_status, char *domain) { struct sss_cmd_ctx *nctx; @@ -158,7 +133,9 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) if (pd == NULL) return ENOMEM; sss_packet_get_body(cctx->creq->in, &body, &blen); - if (body[blen -1] != '\0') { + fprintf(stderr,"\n"); + if (blen >= sizeof(uint32_t) && + ((uint32_t *)(&body[blen - sizeof(uint32_t)]))[0] != END_OF_PAM_REQUEST) { DEBUG(1, ("Received data not terminated.\n")); talloc_free(pd); return EINVAL; @@ -167,13 +144,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) i=0; str=body; while (i<blen) { - /* - if (body[i] == '\0') { - DEBUG(4, ("Received data: %s\n", str)); - str=&body[i+1]; - } - */ - DEBUG(4, ("Received data: %x\n", body[i])); + DEBUG(4, ("Received data: %x\n", body[i])); i++; } diff --git a/server/providers/ldap_be.c b/server/providers/ldap_be.c index d43ed8eb2..a29773f35 100644 --- a/server/providers/ldap_be.c +++ b/server/providers/ldap_be.c @@ -34,6 +34,10 @@ struct ldap_ctx { char *ldap_uri; + char *default_bind_dn; + char *default_authtok_type; + uint32_t default_authtok_size; + char *default_authtok; }; static int ldap_pam_chauthtok(LDAP *ldap, char *dn, uint32_t authtok_size, @@ -101,20 +105,20 @@ cleanup: static int ldap_be_init(LDAP **ldap, struct ldap_ctx *ldap_ctx) { int ret; - int pam_status=PAM_SUCCESS; + int status=EOK; int ldap_vers = LDAP_VERSION3; ret = ldap_initialize(ldap, ldap_ctx->ldap_uri); if (ret != LDAP_SUCCESS) { DEBUG(1, ("ldap_initialize failed: %s\n", strerror(errno))); - return PAM_SYSTEM_ERR; + return EIO; } /* LDAPv3 is needed for TLS */ ret = ldap_set_option(*ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_vers); if ( ret != LDAP_OPT_SUCCESS) { DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret))); - pam_status = PAM_SYSTEM_ERR; + status = EIO; goto cleanup; } @@ -124,104 +128,82 @@ static int ldap_be_init(LDAP **ldap, struct ldap_ctx *ldap_ctx) { ret = ldap_start_tls_s(*ldap, NULL, NULL); if ( ret != LDAP_SUCCESS) { DEBUG(1, ("ldap_start_tls_s failed: %s\n", ldap_err2string(ret))); - pam_status = PAM_SYSTEM_ERR; + status = EIO; goto cleanup; } - return PAM_SUCCESS; + return EOK; cleanup: ldap_unbind_ext(*ldap, NULL, NULL); - return pam_status; + return status; } -static int ldap_be_bind(LDAP *ldap, struct ldap_ctx *ldap_ctx, char *dn, struct berval *pw) { +static int ldap_be_bind(LDAP *ldap, struct ldap_ctx *ldap_ctx, char *dn, struct berval *pw, int *ldap_ret) { int ret; - int pam_status; + int status=EOK; int msgid; - int ldap_ret; LDAPMessage *result=NULL; + char *errmsgp = NULL; + + if ( dn == NULL && ldap_ctx->default_bind_dn != NULL ) { + dn = ldap_ctx->default_bind_dn; + pw->bv_len = ldap_ctx->default_authtok_size; + pw->bv_val = ldap_ctx->default_authtok; + } + DEBUG(3, ("Trying to bind as [%s][%*s]\n", dn, pw->bv_len, pw->bv_val)); ret = ldap_sasl_bind(ldap, dn, LDAP_SASL_SIMPLE, pw, NULL, NULL, &msgid); - if ( msgid == -1 ) { + if ( ret == -1 || msgid == -1 ) { DEBUG(1, ("ldap_bind failed\n")); - return PAM_SYSTEM_ERR; + return EIO; } ret = ldap_result(ldap, msgid, FALSE, NULL, &result); if ( ret == -1 ) { DEBUG(1, ("ldap_result failed.\n")); - pam_status = PAM_SYSTEM_ERR; + status = EIO; goto cleanup; } - ret = ldap_parse_result(ldap, result, &ldap_ret, NULL, NULL, NULL, NULL, 0); + + ret = ldap_parse_result(ldap, result, ldap_ret, NULL, &errmsgp, + NULL, NULL, 0); if ( ret != LDAP_SUCCESS ) { DEBUG(1, ("ldap_parse_result failed.\n")); - pam_status = PAM_SYSTEM_ERR; + status = EIO; goto cleanup; } - DEBUG(3, ("Bind result: [%d][%s]\n", ldap_ret, ldap_err2string(ldap_ret))); + DEBUG(3, ("Bind result: [%d][%s][%s]\n", *ldap_ret, + ldap_err2string(*ldap_ret), errmsgp)); cleanup: + ldap_memfree(errmsgp); ldap_msgfree(result); - return pam_status; + return status; } -static int ldap_pam_handler(struct be_ctx *be_ctx, - const char *user, - uint32_t cmd, const char *tty, - const char *ruser, const char *rhost, - uint32_t authtok_type, uint32_t authtok_size, - char *authtok, - uint32_t newauthtok_type, uint32_t newauthtok_size, - char *newauthtok) { +static int pam_setup_ldap_connection(LDAP *ldap, struct ldap_ctx *ldap_ctx, + const char *user, uint32_t authtok_type, + uint32_t authtok_size, char *authtok, + char **dn) { int msgid; int ret; int pam_status=PAM_SUCCESS; - struct ldap_ctx *ldap_ctx; - LDAP *ldap; LDAPMessage *result=NULL; LDAPMessage *msg=NULL; - char *dn=NULL; char *filter=NULL; char *attrs[] = { LDAP_NO_ATTRS, NULL }; struct berval userpw; int ldap_ret; - ldap_ctx = talloc_get_type(be_ctx->pvt_data, struct ldap_ctx); - - ret = ldap_be_init(&ldap, ldap_ctx); - if (ret != PAM_SUCCESS) { - DEBUG(1, ("ldap_be_init failed: %s\n", strerror(errno))); - return PAM_SYSTEM_ERR; - } - userpw.bv_len = 0; userpw.bv_val = 0; - - ret = ldap_sasl_bind(ldap, NULL, LDAP_SASL_SIMPLE, &userpw, NULL, NULL, - &msgid); - if ( msgid == -1 ) { - DEBUG(1, ("ldap_bind failed\n")); - return PAM_SYSTEM_ERR; - } - - ret = ldap_result(ldap, msgid, FALSE, NULL, &result); - if ( ret == -1 ) { - DEBUG(1, ("ldap_result failed.\n")); - pam_status = PAM_SYSTEM_ERR; - goto cleanup; - } - ret = ldap_parse_result(ldap, result, &ldap_ret, NULL, NULL, NULL, NULL, 0); - if ( ret != LDAP_SUCCESS ) { - DEBUG(1, ("ldap_parse_result failed.\n")); + ret = ldap_be_bind(ldap, ldap_ctx, NULL, &userpw, &ldap_ret); + if (ret != EOK) { + DEBUG(1, ("ldap_be_bind failed.\n")); pam_status = PAM_SYSTEM_ERR; - goto cleanup; } - DEBUG(3, ("Bind result: [%d][%s]\n", ldap_ret, ldap_err2string(ldap_ret))); - - ldap_msgfree(result); filter = talloc_asprintf(ldap_ctx, "(&(uid=%s)(objectclass=posixAccount))", user); @@ -243,10 +225,7 @@ static int ldap_pam_handler(struct be_ctx *be_ctx, goto cleanup; } - talloc_free(filter); - - - ret = ldap_result(ldap, msgid, FALSE, NULL, &result); + ret = ldap_result(ldap, msgid, TRUE, NULL, &result); if ( ret == -1 ) { DEBUG(1, ("ldap_result failed.\n")); pam_status = PAM_SYSTEM_ERR; @@ -260,46 +239,46 @@ static int ldap_pam_handler(struct be_ctx *be_ctx, goto cleanup; } - dn = ldap_get_dn(ldap, msg); - if ( dn == NULL ) { - DEBUG(1, ("ldap_get_dn failed.\n")); - pam_status = PAM_SYSTEM_ERR; - goto cleanup; - } - - if ( *dn == '\0' ) { - DEBUG(1, ("No user found.\n")); - pam_status = PAM_USER_UNKNOWN; - goto cleanup; - } - DEBUG(3, ("Found dn: %s\n",dn)); - - /* TODO: check for more results */ - ldap_msgfree(result); - result = NULL; + *dn = NULL; + do { + switch ( ldap_msgtype(msg) ) { + case LDAP_RES_SEARCH_ENTRY: + if ( *dn != NULL ) { + DEBUG(1, ("Found more than one object with filter [%s].\n", + filter)); + pam_status = PAM_SYSTEM_ERR; + goto cleanup; + } + *dn = ldap_get_dn(ldap, msg); + if ( *dn == NULL ) { + DEBUG(1, ("ldap_get_dn failed.\n")); + pam_status = PAM_SYSTEM_ERR; + goto cleanup; + } + + if ( **dn == '\0' ) { + DEBUG(1, ("No user found.\n")); + pam_status = PAM_USER_UNKNOWN; + goto cleanup; + } + DEBUG(3, ("Found dn: %s\n",*dn)); + + ldap_msgfree(result); + result = NULL; + break; + default: + DEBUG(3, ("ignoring message with type %d.\n", ldap_msgtype(msg))); + } + } while( (msg=ldap_next_message(ldap, msg)) != NULL ); userpw.bv_val = authtok; userpw.bv_len = authtok_size; - ret = ldap_sasl_bind(ldap, dn, LDAP_SASL_SIMPLE, &userpw, NULL, NULL, - &msgid); - if ( msgid == -1 ) { - DEBUG(1, ("ldap_bind failed\n")); - return PAM_SYSTEM_ERR; - } - - ret = ldap_result(ldap, msgid, FALSE, NULL, &result); - if ( ret == -1 ) { - DEBUG(1, ("ldap_result failed.\n")); - pam_status = PAM_SYSTEM_ERR; - goto cleanup; - } - ret = ldap_parse_result(ldap, result, &ldap_ret, NULL, NULL, NULL, NULL, 0); - if ( ret != LDAP_SUCCESS ) { - DEBUG(1, ("ldap_parse_result failed.\n")); + ret = ldap_be_bind(ldap, ldap_ctx, *dn, &userpw, &ldap_ret); + if (ret != EOK) { + DEBUG(1, ("ldap_be_bind failed.\n")); pam_status = PAM_SYSTEM_ERR; goto cleanup; } - DEBUG(3, ("Bind result: [%d][%s]\n", ldap_ret, ldap_err2string(ldap_ret))); switch (ldap_ret) { case LDAP_SUCCESS: @@ -307,20 +286,73 @@ static int ldap_pam_handler(struct be_ctx *be_ctx, break; case LDAP_INVALID_CREDENTIALS: pam_status = PAM_CRED_INSUFFICIENT; + goto cleanup; break; default: pam_status = PAM_SYSTEM_ERR; + goto cleanup; } - if ( cmd == SSS_PAM_CHAUTHTOK ) { - pam_status = ldap_pam_chauthtok(ldap, dn, authtok_size, authtok, - newauthtok_size, newauthtok); +cleanup: + talloc_free(filter); + ldap_msgfree(result); + + return pam_status; +} + + +static int ldap_pam_handler(struct be_ctx *be_ctx, + const char *user, + uint32_t cmd, const char *tty, + const char *ruser, const char *rhost, + uint32_t authtok_type, uint32_t authtok_size, + char *authtok, + uint32_t newauthtok_type, uint32_t newauthtok_size, + char *newauthtok) { + int ret; + int pam_status=PAM_SUCCESS; + struct ldap_ctx *ldap_ctx; + LDAP *ldap; + char *dn=NULL; + + ldap_ctx = talloc_get_type(be_ctx->pvt_data, struct ldap_ctx); + + ret = ldap_be_init(&ldap, ldap_ctx); + if (ret != EOK) { + DEBUG(1, ("ldap_be_init failed.\n")); + return PAM_SYSTEM_ERR; } + ret = pam_setup_ldap_connection(ldap, ldap_ctx, user, authtok_type, + authtok_size, authtok, &dn); + if ( ret != PAM_SUCCESS ) { + DEBUG(1, ("pam_setup_ldap_connection failed.\n")); + pam_status = ret; + goto cleanup; + } + DEBUG(3, ("Successfully conected as %s.\n", dn)); + + switch (cmd) { + case SSS_PAM_AUTHENTICATE: + pam_status = PAM_SUCCESS; + break; + case SSS_PAM_CHAUTHTOK: + pam_status = ldap_pam_chauthtok(ldap, dn, authtok_size, authtok, + newauthtok_size, newauthtok); + break; + case SSS_PAM_ACCT_MGMT: + case SSS_PAM_SETCRED: + case SSS_PAM_OPEN_SESSION: + case SSS_PAM_CLOSE_SESSION: + pam_status = PAM_SUCCESS; + break; + default: + DEBUG(1, ("Unknown pam command %d.\n", cmd)); + pam_status = PAM_SYSTEM_ERR; + } cleanup: ldap_memfree(dn); - ldap_msgfree(result); ldap_unbind_ext(ldap, NULL, NULL); return pam_status; } @@ -336,6 +368,9 @@ int sssm_ldap_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_dat { struct ldap_ctx *ctx; char *ldap_uri; + char *default_bind_dn; + char *default_authtok_type; + char *default_authtok; int ret; ctx = talloc(bectx, struct ldap_ctx); @@ -346,13 +381,27 @@ int sssm_ldap_init(struct be_ctx *bectx, struct be_mod_ops **ops, void **pvt_dat ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, "ldapUri", "ldap://localhost", &ldap_uri); if (ret != EOK) goto done; - if (ldap_uri == NULL) { - ret = ENOENT; - goto done; - } - ctx->ldap_uri = ldap_uri; + ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, + "defaultBindDn", NULL, &default_bind_dn); + if (ret != EOK) goto done; + ctx->default_bind_dn = default_bind_dn; + + ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, + "defaultAuthtokType", NULL, &default_authtok_type); + if (ret != EOK) goto done; + ctx->default_authtok_type = default_authtok_type; + + +/* TODO: better to have a blob object than a string here */ + ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, + "defaultAuthtok", NULL, &default_authtok); + if (ret != EOK) goto done; + ctx->default_authtok = default_authtok; + ctx->default_authtok_size = (default_authtok==NULL?0:strlen(default_authtok)); + + *ops = &ldap_mod_ops; *pvt_data = ctx; diff --git a/server/server.mk b/server/server.mk index 7f9665905..f4b5f078d 100644 --- a/server/server.mk +++ b/server/server.mk @@ -58,7 +58,7 @@ SYSDB_TEST_OBJ = \ PAMSRV_OBJ = \ nss/pamsrv.o \ nss/pamsrv_cmd.o \ - nss/pamsrv_dp.o + nss/pamsrv_dp.o PAM = -lpam diff --git a/server/util/ssssrv_common.c b/server/util/ssssrv_common.c index 57f5fce43..6c45ea6ae 100644 --- a/server/util/ssssrv_common.c +++ b/server/util/ssssrv_common.c @@ -322,9 +322,9 @@ failed: /* domain names are case insensitive for now * NOTE: this function is not utf-8 safe, * only ASCII names for now */ -static int _domain_comparator(void *key1, void *key2) +static int _domain_comparator(const void *key1, const void *key2) { - return strcasecmp((char *)key1, (char *)key2); + return strcasecmp((const char *)key1, (const char *)key2); } static int sss_init_domains(struct nss_ctx *nctx) @@ -348,7 +348,7 @@ static int sss_init_domains(struct nss_ctx *nctx) /* Look up the appropriate basedn for this domain */ ret = confdb_get_domain_basedn(nctx->cdb, tmp_ctx, domains[i], &basedn); DEBUG(3, ("BaseDN: %s\n", basedn)); - btreemap_set_value(&nctx->domain_map, domains[i], basedn, _domain_comparator); + btreemap_set_value(nctx, &nctx->domain_map, domains[i], basedn, _domain_comparator); i++; } if (i == 0) { @@ -438,7 +438,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx, return EOK; } -static int sss_parse_name(TALLOC_CTX *memctx, +int sss_parse_name(TALLOC_CTX *memctx, const char *fullname, struct btreemap *domain_map, const char **domain, const char **name) { diff --git a/server/util/ssssrv_common.h b/server/util/ssssrv_common.h index ed7bf3839..0f9b7c8be 100644 --- a/server/util/ssssrv_common.h +++ b/server/util/ssssrv_common.h @@ -18,7 +18,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx, const char *confdb_socket_path, struct sbus_method dp_methods[]); -static int sss_parse_name(TALLOC_CTX *memctx, - const char *fullname, - struct btreemap *domain_map, - const char **domain, const char **name); +int sss_parse_name(TALLOC_CTX *memctx, + const char *fullname, + struct btreemap *domain_map, + const char **domain, const char **name); diff --git a/sss_client/Makefile.in b/sss_client/Makefile.in index 59880f494..6d80f83c3 100644 --- a/sss_client/Makefile.in +++ b/sss_client/Makefile.in @@ -30,9 +30,11 @@ NSS_SSS_OBJS = common.o passwd.o group.o PAM_SSS_SOLIB = pam_sss.$(SHLIBEXT) PAM_SSS_OBJS = pam_sss.o common.o -PAM_LIBS = -lpam +PAM_LIBS = -lpam -lpam_misc PAM_CFLAGS = -DDEBUG -g -Wall -Werror +PAM_CLIENT = pam_test_client +PAM_CLIENT_OBJS = pam_test_client.o default: all @@ -58,11 +60,14 @@ $(NSS_SSS_SONAME): $(NSS_SSS_SOLIB) pam_sss.o: pam_sss.c @echo Compiling $*.c @$(CC) $(PICFLAG) $(CFLAGS) $(PAM_CFLAGS) -c $< -o $@ - + +$(PAM_CLIENT): $(PAM_CLIENT_OBJS) + @$(CC) $(CFLAGS) $(PAM_CFLAGS) $< -o $@ $(PAM_LIBS) + $(PAM_SSS_SOLIB): $(PAM_SSS_OBJS) $(SHLD) $(SHLD_FLAGS) -o $@ $(PAM_SSS_OBJS) $(PAM_LIBS) -all: showflags $(NSS_SSS_OBJS) $(NSS_SSS_SOLIB) $(NSS_SSS_SONAME) $(PAM_SSS_SOLIB) +all: showflags $(NSS_SSS_OBJS) $(NSS_SSS_SOLIB) $(NSS_SSS_SONAME) $(PAM_SSS_SOLIB) $(PAM_CLIENT) install: all $(INSTALLCMD) -m 755 $(NSS_SSS_SOLIB) /lib @@ -70,7 +75,7 @@ install: all clean: rm -f *.o *.a */*.o - rm -f $(NSS_SSS_SOLIB) $(NSS_SSS_SONAME) $(PAM_SSS_SOLIB) + rm -f $(NSS_SSS_SOLIB) $(NSS_SSS_SONAME) $(PAM_SSS_SOLIB) $(PAM_CLIENT) distclean: clean rm -f config.log config.status config.h config.cache diff --git a/sss_client/pam_sss.c b/sss_client/pam_sss.c index 82ef62e3e..4fce6a04f 100644 --- a/sss_client/pam_sss.c +++ b/sss_client/pam_sss.c @@ -26,7 +26,9 @@ struct pam_items { int pam_tty_size; int pam_ruser_size; int pam_rhost_size; + int pam_authtok_type; int pam_authtok_size; + int pam_newauthtok_type; int pam_newauthtok_size; }; @@ -104,8 +106,10 @@ static int pam_sss(int task, pam_handle_t *pamh, int flags, int argc, return ret; } + pi.pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi.pam_authtok = NULL; pi.pam_authtok_size = 0; + pi.pam_newauthtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi.pam_newauthtok = NULL; pi.pam_newauthtok_size = 0; /* according to pam_conv(3) only one message should be requested by conv to @@ -135,9 +139,11 @@ static int pam_sss(int task, pam_handle_t *pamh, int flags, int argc, if (resp[0].resp == NULL) { D(("Empty password\n")); - pi.pam_authtok = strdup(""); + pi.pam_authtok = NULL; + pi.pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY; } else { pi.pam_authtok = strdup(resp[0].resp); + pi.pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; } pi.pam_authtok_size=strlen(pi.pam_authtok); } @@ -166,9 +172,11 @@ static int pam_sss(int task, pam_handle_t *pamh, int flags, int argc, if (resp[0].resp == NULL) { D(("Empty password\n")); - pi.pam_newauthtok = strdup(""); + pi.pam_newauthtok = NULL; + pi.pam_newauthtok_type = SSS_AUTHTOK_TYPE_EMPTY; } else { pi.pam_newauthtok = strdup(resp[0].resp); + pi.pam_newauthtok_type = SSS_AUTHTOK_TYPE_PASSWORD; } pi.pam_newauthtok_size=strlen(pi.pam_newauthtok); } @@ -180,11 +188,10 @@ static int pam_sss(int task, pam_handle_t *pamh, int flags, int argc, pi.pam_service_size + pi.pam_tty_size + pi.pam_ruser_size + - pi.pam_rhost_size; - if (1 || task == SSS_PAM_AUTHENTICATE || task == SSS_PAM_CHAUTHTOK) - rd.len += 2*sizeof(uint32_t) + pi.pam_authtok_size; - if (1 || task == SSS_PAM_CHAUTHTOK) - rd.len += 2*sizeof(uint32_t) + pi.pam_newauthtok_size; + pi.pam_rhost_size + + 2*sizeof(uint32_t) + pi.pam_authtok_size + + 2*sizeof(uint32_t) + pi.pam_newauthtok_size + + sizeof(uint32_t); buf = malloc(sizeof(char)*rd.len); memcpy(buf, pi.pam_user, pi.pam_user_size); @@ -202,28 +209,26 @@ static int pam_sss(int task, pam_handle_t *pamh, int flags, int argc, memcpy(&buf[rp], pi.pam_rhost, pi.pam_rhost_size); rp += pi.pam_rhost_size; -/* FIXME */ - if (1 || task == SSS_PAM_AUTHENTICATE || task == SSS_PAM_CHAUTHTOK) { - ((uint32_t *)(&buf[rp]))[0] = SSS_AUTHTOK_TYPE_PASSWORD; - rp += sizeof(uint32_t); - ((uint32_t *)(&buf[rp]))[0] = pi.pam_authtok_size; - rp += sizeof(uint32_t); - memcpy(&buf[rp], pi.pam_authtok, pi.pam_authtok_size); - rp += pi.pam_authtok_size; - _pam_overwrite((void *)pi.pam_authtok); - free((void *)pi.pam_authtok); - } - - if (1 || task == SSS_PAM_CHAUTHTOK) { - ((uint32_t *)(&buf[rp]))[0] = SSS_AUTHTOK_TYPE_PASSWORD; - rp += sizeof(uint32_t); - ((uint32_t *)(&buf[rp]))[0] = pi.pam_newauthtok_size; - rp += sizeof(uint32_t); - memcpy(&buf[rp], pi.pam_newauthtok, pi.pam_newauthtok_size); - rp += pi.pam_newauthtok_size; - _pam_overwrite((void *)pi.pam_newauthtok); - free((void *)pi.pam_newauthtok); - } + ((uint32_t *)(&buf[rp]))[0] = pi.pam_authtok_type; + rp += sizeof(uint32_t); + ((uint32_t *)(&buf[rp]))[0] = pi.pam_authtok_size; + rp += sizeof(uint32_t); + memcpy(&buf[rp], pi.pam_authtok, pi.pam_authtok_size); + rp += pi.pam_authtok_size; + _pam_overwrite((void *)pi.pam_authtok); + free((void *)pi.pam_authtok); + + ((uint32_t *)(&buf[rp]))[0] = pi.pam_newauthtok_type; + rp += sizeof(uint32_t); + ((uint32_t *)(&buf[rp]))[0] = pi.pam_newauthtok_size; + rp += sizeof(uint32_t); + memcpy(&buf[rp], pi.pam_newauthtok, pi.pam_newauthtok_size); + rp += pi.pam_newauthtok_size; + _pam_overwrite((void *)pi.pam_newauthtok); + free((void *)pi.pam_newauthtok); + + ((uint32_t *)(&buf[rp]))[0] = END_OF_PAM_REQUEST; + rp += sizeof(uint32_t); if (rp != rd.len) { D(("error during packet creation.")); diff --git a/sss_client/sss_cli.h b/sss_client/sss_cli.h index 659a0dd74..1d471f2f4 100644 --- a/sss_client/sss_cli.h +++ b/sss_client/sss_cli.h @@ -131,9 +131,12 @@ enum sss_cli_command { }; enum sss_authtok_type { + SSS_AUTHTOK_TYPE_EMPTY = 0x0000, SSS_AUTHTOK_TYPE_PASSWORD = 0x0001, }; +#define END_OF_PAM_REQUEST 0x4950414d + #define SSS_NSS_MAX_ENTRIES 256 #define SSS_NSS_HEADER_SIZE (sizeof(uint32_t) * 4) struct sss_cli_req_data { |