Merge LDAP filter parinoia from HEAD, a few other pdb_ldap updates and some
authorAndrew Bartlett <abartlet@samba.org>
Sat, 1 Feb 2003 07:59:29 +0000 (07:59 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 1 Feb 2003 07:59:29 +0000 (07:59 +0000)
misc libads fixes.

Andrew Bartlett
(This used to be commit 9c3a1710efba9fa4160004a554687d4b85927bb1)

source3/Makefile.in
source3/libads/ldap.c
source3/libads/ldap_user.c
source3/passdb/pdb_ldap.c
source3/utils/net_ads.c

index 40210e5a94e1b8ff6f9a48548dd733463cce6feb..8668cdf1f16dbb784de4331a1bf84f77231a9ece 100644 (file)
@@ -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
 
index 0a95e019bfb5b7317a04365a6acb307a8d86e994..603f17c9948ad14d52d2e9b224219d33196b3d5b 100644 (file)
@@ -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;
index 2e38e7a00d1dae74a578cb1709e37f683babcc2c..7efe5338f371bb7e8b81a6a3a3e0cad3dfbc0511 100644 (file)
@@ -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;
 }
 
index 7e443a97c6166102ff6931d0e085f4d7d22b64b3..e058d2d1084fff69b3521c3d20bbd9e422a6c6e7 100644 (file)
@@ -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;
        }
index 29abc33fdf53347987231b63e8db86c48245bf29..867252c95f2ac9743b1d44ad0e7e271510892eae 100644 (file)
@@ -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);