From 963e88aa90853a7e45c72cbc6630aa705b6d4e55 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 1 Feb 2003 07:59:29 +0000 Subject: Merge LDAP filter parinoia from HEAD, a few other pdb_ldap updates and some misc libads fixes. Andrew Bartlett (This used to be commit 9c3a1710efba9fa4160004a554687d4b85927bb1) --- source3/Makefile.in | 3 +- source3/libads/ldap.c | 28 ++++++++++++----- source3/libads/ldap_user.c | 9 ++++-- source3/passdb/pdb_ldap.c | 76 +++++++++++++++++++++++++++++++++++----------- source3/utils/net_ads.c | 8 ++++- 5 files changed, 96 insertions(+), 28 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index 40210e5a94..8668cdf1f1 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -155,7 +155,8 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.o \ nsswitch/wb_client.o nsswitch/wb_common.o \ lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \ - lib/adt_tree.o lib/gencache.o $(TDB_OBJ) + lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \ + lib/ldap_escape.o LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0a95e019bf..603f17c994 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -974,7 +974,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, utf8_dn ? utf8_dn : new_dn, mods); + ret = ldap_add_s(ads->ld, utf8_dn, mods); SAFE_FREE(utf8_dn); return ADS_ERROR(ret); } @@ -994,7 +994,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - ret = ldap_delete(ads->ld, utf8_dn ? utf8_dn : del_dn); + ret = ldap_delete(ads->ld, utf8_dn); return ADS_ERROR(ret); } @@ -1029,8 +1029,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ADS_MODLIST mods; const char *objectClass[] = {"top", "person", "organizationalPerson", "user", "computer", NULL}; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - char *psp; + const char *servicePrincipalName[5] = {NULL, NULL, NULL, NULL, NULL}; + char *psp, *psp2; unsigned acct_control; if (!(ctx = talloc_init("machine_account"))) @@ -1051,10 +1051,16 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads->config.bind_path); servicePrincipalName[0] = talloc_asprintf(ctx, "HOST/%s", hostname); psp = talloc_asprintf(ctx, "HOST/%s.%s", - hostname, - ads->config.realm); + hostname, + ads->config.realm); strlower(&psp[5]); servicePrincipalName[1] = psp; + servicePrincipalName[2] = talloc_asprintf(ctx, "CIFS/%s", hostname); + psp2 = talloc_asprintf(ctx, "CIFS/%s.%s", + hostname, + ads->config.realm); + strlower(&psp2[5]); + servicePrincipalName[3] = psp2; free(ou_str); if (!new_dn) @@ -1405,6 +1411,7 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) size_t sd_size = 0; struct berval bval = {0, NULL}; prs_struct ps_wire; + char *escaped_hostname = escape_ldap_string_alloc(hostname); LDAPMessage *res = 0; LDAPMessage *msg = 0; @@ -1420,11 +1427,18 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) ret = ADS_ERROR(LDAP_SUCCESS); - if (asprintf(&exp, "(samAccountName=%s$)", hostname) == -1) { + if (!escaped_hostname) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + + if (asprintf(&exp, "(samAccountName=%s$)", escaped_hostname) == -1) { DEBUG(1, ("ads_set_machine_sd: asprintf failed!\n")); + SAFE_FREE(escaped_hostname); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } + SAFE_FREE(escaped_hostname); + ret = ads_search(ads, (void *) &res, exp, attrs); if (!ADS_ERR_OK(ret)) return ret; diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c index 2e38e7a00d..7efe5338f3 100644 --- a/source3/libads/ldap_user.c +++ b/source3/libads/ldap_user.c @@ -30,10 +30,15 @@ ADS_STATUS ads_find_user_acct(ADS_STRUCT *ads, void **res, const char *user) ADS_STATUS status; char *exp; const char *attrs[] = {"*", NULL}; + char *escaped_user = escape_ldap_string_alloc(user); + if (!escaped_user) { + return ADS_ERROR(LDAP_NO_MEMORY); + } - asprintf(&exp, "(samAccountName=%s)", user); + asprintf(&exp, "(samAccountName=%s)", escaped_user); status = ads_search(ads, res, exp, attrs); - free(exp); + SAFE_FREE(exp); + SAFE_FREE(escaped_user); return status; } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 7e443a97c6..e058d2d108 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -218,7 +218,7 @@ static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** DEBUG(3,("LDAPS option set...!\n")); #else - DEBUG(0,("ldap_open_connection: Secure connection not supported by LDAP client libraries!\n")); + DEBUG(0,("ldapsam_open_connection: Secure connection not supported by LDAP client libraries!\n")); return LDAP_OPERATIONS_ERROR; #endif } @@ -254,12 +254,12 @@ static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** return LDAP_OPERATIONS_ERROR; } #else - DEBUG(0,("ldap_open_connection: StartTLS not supported by LDAP client libraries!\n")); + DEBUG(0,("ldapsam_open_connection: StartTLS not supported by LDAP client libraries!\n")); return LDAP_OPERATIONS_ERROR; #endif } - DEBUG(2, ("ldap_open_connection: connection opened\n")); + DEBUG(2, ("ldapsam_open_connection: connection opened\n")); return rc; } @@ -284,7 +284,7 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, memset(*credp, '\0', strlen(*credp)); SAFE_FREE(*credp); } else { - DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", + DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n", ldap_state->bind_dn)); *whop = strdup(ldap_state->bind_dn); @@ -315,7 +315,7 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct, { struct ldapsam_privates *ldap_state = arg; int rc; - DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", + DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n", ldap_state->bind_dn)); /** @TODO Should we be doing something to check what servers we rebind to? @@ -385,8 +385,8 @@ static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ld /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite (OpenLDAP) doesnt' seem to support it */ - DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n", - ldap_dn)); + DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n", + ldap_state->uri, ldap_dn)); #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) # if LDAP_SET_REBIND_PROC_ARGS == 2 @@ -407,7 +407,14 @@ static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ld rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); if (rc != LDAP_SUCCESS) { - DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc))); + char *ld_error; + ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0, + ("failed to bind to server with dn= %s Error: %s\n\t%s\n", + ldap_dn, ldap_err2string(rc), + ld_error)); + free(ld_error); return rc; } @@ -659,7 +666,12 @@ static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, LDAPMessage ** result) { pstring filter; - + char *escape_user = escape_ldap_string_alloc(user); + + if (!escape_user) { + return LDAP_NO_MEMORY; + } + /* * in the filter expression, replace %u with the real name * so in ldap filter, %u MUST exist :-) @@ -670,7 +682,10 @@ static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, * have to use this here because $ is filtered out * in pstring_sub */ - all_string_sub(filter, "%u", user, sizeof(pstring)); + + + all_string_sub(filter, "%u", escape_user, sizeof(pstring)); + SAFE_FREE(escape_user); return ldapsam_search_one_user(ldap_state, filter, result); } @@ -684,6 +699,7 @@ static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, { struct passwd *user; pstring filter; + char *escape_user; /* Get the username from the system and look that up in the LDAP */ @@ -694,9 +710,16 @@ static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state, pstrcpy(filter, lp_ldap_filter()); - all_string_sub(filter, "%u", user->pw_name, sizeof(pstring)); + escape_user = escape_ldap_string_alloc(user->pw_name); + if (!escape_user) { + passwd_free(&user); + return LDAP_NO_MEMORY; + } + + all_string_sub(filter, "%u", escape_user, sizeof(pstring)); passwd_free(&user); + SAFE_FREE(escape_user); return ldapsam_search_one_user(ldap_state, filter, result); } @@ -1558,16 +1581,26 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAPMessage *result; LDAPMessage *entry; - + int count; + if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) { return NT_STATUS_NO_SUCH_USER; } - if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) { + + count = ldap_count_entries(ldap_state->ldap_struct, result); + + if (count < 1) { DEBUG(4, ("We don't find this user [%s] count=%d\n", sname, - ldap_count_entries(ldap_state->ldap_struct, result))); + count)); + return NT_STATUS_NO_SUCH_USER; + } else if (count > 1) { + DEBUG(1, + ("Duplicate entries for this user [%s] Failing. count=%d\n", sname, + count)); return NT_STATUS_NO_SUCH_USER; } + entry = ldap_first_entry(ldap_state->ldap_struct, result); if (entry) { if (!init_sam_from_ldap(ldap_state, user, entry)) { @@ -1593,15 +1626,23 @@ static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT (struct ldapsam_privates *)my_methods->private_data; LDAPMessage *result; LDAPMessage *entry; + int count; if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) { return NT_STATUS_NO_SUCH_USER; } - if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) { + count = ldap_count_entries(ldap_state->ldap_struct, result); + + if (count < 1) { DEBUG(4, ("We don't find this rid [%i] count=%d\n", rid, - ldap_count_entries(ldap_state->ldap_struct, result))); + count)); + return NT_STATUS_NO_SUCH_USER; + } else if (count > 1) { + DEBUG(1, + ("More than one user with rid [%i]. Failing. count=%d\n", rid, + count)); return NT_STATUS_NO_SUCH_USER; } @@ -1853,7 +1894,8 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO } if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) { - DEBUG(0,("User already in the base, with samba properties\n")); + DEBUG(0,("User '%s' already in the base, with samba properties\n", + username)); ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 29abc33fdf..867252c95f 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -308,12 +308,18 @@ static int ads_user_info(int argc, const char **argv) const char *attrs[] = {"memberOf", NULL}; char *searchstring=NULL; char **grouplist; + char *escaped_user = escape_ldap_string_alloc(argv[0]); if (argc < 1) return net_ads_user_usage(argc, argv); if (!(ads = ads_startup())) return -1; - asprintf(&searchstring, "(sAMAccountName=%s)", argv[0]); + if (!escaped_user) { + d_printf("ads_user_info: failed to escape user %s\n", argv[0]); + return -1; + } + + asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user); rc = ads_search(ads, &res, searchstring, attrs); safe_free(searchstring); -- cgit