Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/lib/smbldap.c

    r740 r988  
    2525#include "includes.h"
    2626#include "smbldap.h"
    27 #include "secrets.h"
    2827#include "../libcli/security/security.h"
     28#include <tevent.h>
     29#include "lib/param/loadparm.h"
    2930
    3031/* Try not to hit the up or down server forever */
     
    3536#define SMBLDAP_IDLE_TIME 150           /* After 2.5 minutes disconnect */
    3637
    37 
    38 /* attributes used by Samba 2.2 */
    39 
    40 ATTRIB_MAP_ENTRY attrib_map_v22[] = {
    41         { LDAP_ATTR_UID,                "uid"           },
    42         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
    43         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
    44         { LDAP_ATTR_UNIX_HOME,          "homeDirectory" },
    45         { LDAP_ATTR_PWD_LAST_SET,       "pwdLastSet"    },
    46         { LDAP_ATTR_PWD_CAN_CHANGE,     "pwdCanChange"  },
    47         { LDAP_ATTR_PWD_MUST_CHANGE,    "pwdMustChange" },
    48         { LDAP_ATTR_LOGON_TIME,         "logonTime"     },
    49         { LDAP_ATTR_LOGOFF_TIME,        "logoffTime"    },
    50         { LDAP_ATTR_KICKOFF_TIME,       "kickoffTime"   },
    51         { LDAP_ATTR_CN,                 "cn"            },
    52         { LDAP_ATTR_SN,                 "sn"            },
    53         { LDAP_ATTR_DISPLAY_NAME,       "displayName"   },
    54         { LDAP_ATTR_HOME_PATH,          "smbHome"       },
    55         { LDAP_ATTR_HOME_DRIVE,         "homeDrive"     },
    56         { LDAP_ATTR_LOGON_SCRIPT,       "scriptPath"    },
    57         { LDAP_ATTR_PROFILE_PATH,       "profilePath"   },
    58         { LDAP_ATTR_DESC,               "description"   },
    59         { LDAP_ATTR_USER_WKS,           "userWorkstations"},
    60         { LDAP_ATTR_USER_RID,           "rid"           },
    61         { LDAP_ATTR_PRIMARY_GROUP_RID,  "primaryGroupID"},
    62         { LDAP_ATTR_LMPW,               "lmPassword"    },
    63         { LDAP_ATTR_NTPW,               "ntPassword"    },
    64         { LDAP_ATTR_DOMAIN,             "domain"        },
    65         { LDAP_ATTR_OBJCLASS,           "objectClass"   },
    66         { LDAP_ATTR_ACB_INFO,           "acctFlags"     },
    67         { LDAP_ATTR_MOD_TIMESTAMP,      "modifyTimestamp"       },
    68         { LDAP_ATTR_LIST_END,           NULL            }
    69 };
    70 
    71 ATTRIB_MAP_ENTRY attrib_map_to_delete_v22[] = {
    72         { LDAP_ATTR_PWD_LAST_SET,       "pwdLastSet"    },
    73         { LDAP_ATTR_PWD_CAN_CHANGE,     "pwdCanChange"  },
    74         { LDAP_ATTR_PWD_MUST_CHANGE,    "pwdMustChange" },
    75         { LDAP_ATTR_LOGON_TIME,         "logonTime"     },
    76         { LDAP_ATTR_LOGOFF_TIME,        "logoffTime"    },
    77         { LDAP_ATTR_KICKOFF_TIME,       "kickoffTime"   },
    78         { LDAP_ATTR_DISPLAY_NAME,       "displayName"   },
    79         { LDAP_ATTR_HOME_PATH,          "smbHome"       },
    80         { LDAP_ATTR_HOME_DRIVE,         "homeDrives"    },
    81         { LDAP_ATTR_LOGON_SCRIPT,       "scriptPath"    },
    82         { LDAP_ATTR_PROFILE_PATH,       "profilePath"   },
    83         { LDAP_ATTR_USER_WKS,           "userWorkstations"},
    84         { LDAP_ATTR_USER_RID,           "rid"           },
    85         { LDAP_ATTR_PRIMARY_GROUP_RID,  "primaryGroupID"},
    86         { LDAP_ATTR_LMPW,               "lmPassword"    },
    87         { LDAP_ATTR_NTPW,               "ntPassword"    },
    88         { LDAP_ATTR_DOMAIN,             "domain"        },
    89         { LDAP_ATTR_ACB_INFO,           "acctFlags"     },
    90         { LDAP_ATTR_LIST_END,           NULL            }
    91 };
    92 
    93 /* attributes used by Samba 3.0's sambaSamAccount */
    94 
    95 ATTRIB_MAP_ENTRY attrib_map_v30[] = {
    96         { LDAP_ATTR_UID,                "uid"                   },
    97         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
    98         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
    99         { LDAP_ATTR_UNIX_HOME,          "homeDirectory"         },
    100         { LDAP_ATTR_PWD_LAST_SET,       "sambaPwdLastSet"       },
    101         { LDAP_ATTR_PWD_CAN_CHANGE,     "sambaPwdCanChange"     },
    102         { LDAP_ATTR_PWD_MUST_CHANGE,    "sambaPwdMustChange"    },
    103         { LDAP_ATTR_LOGON_TIME,         "sambaLogonTime"        },
    104         { LDAP_ATTR_LOGOFF_TIME,        "sambaLogoffTime"       },
    105         { LDAP_ATTR_KICKOFF_TIME,       "sambaKickoffTime"      },
    106         { LDAP_ATTR_CN,                 "cn"                    },
    107         { LDAP_ATTR_SN,                 "sn"                    },
    108         { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
    109         { LDAP_ATTR_HOME_DRIVE,         "sambaHomeDrive"        },
    110         { LDAP_ATTR_HOME_PATH,          "sambaHomePath"         },
    111         { LDAP_ATTR_LOGON_SCRIPT,       "sambaLogonScript"      },
    112         { LDAP_ATTR_PROFILE_PATH,       "sambaProfilePath"      },
    113         { LDAP_ATTR_DESC,               "description"           },
    114         { LDAP_ATTR_USER_WKS,           "sambaUserWorkstations" },
    115         { LDAP_ATTR_USER_SID,           LDAP_ATTRIBUTE_SID      },
    116         { LDAP_ATTR_PRIMARY_GROUP_SID,  "sambaPrimaryGroupSID"  },
    117         { LDAP_ATTR_LMPW,               "sambaLMPassword"       },
    118         { LDAP_ATTR_NTPW,               "sambaNTPassword"       },
    119         { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
    120         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
    121         { LDAP_ATTR_ACB_INFO,           "sambaAcctFlags"        },
    122         { LDAP_ATTR_MUNGED_DIAL,        "sambaMungedDial"       },
    123         { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
    124         { LDAP_ATTR_BAD_PASSWORD_TIME,  "sambaBadPasswordTime"  },
    125         { LDAP_ATTR_PWD_HISTORY,        "sambaPasswordHistory"  },
    126         { LDAP_ATTR_MOD_TIMESTAMP,      "modifyTimestamp"       },
    127         { LDAP_ATTR_LOGON_HOURS,        "sambaLogonHours"       },
    128         { LDAP_ATTR_LIST_END,           NULL                    }
    129 };
    130 
    131 ATTRIB_MAP_ENTRY attrib_map_to_delete_v30[] = {
    132         { LDAP_ATTR_PWD_LAST_SET,       "sambaPwdLastSet"       },
    133         { LDAP_ATTR_PWD_CAN_CHANGE,     "sambaPwdCanChange"     },
    134         { LDAP_ATTR_PWD_MUST_CHANGE,    "sambaPwdMustChange"    },
    135         { LDAP_ATTR_LOGON_TIME,         "sambaLogonTime"        },
    136         { LDAP_ATTR_LOGOFF_TIME,        "sambaLogoffTime"       },
    137         { LDAP_ATTR_KICKOFF_TIME,       "sambaKickoffTime"      },
    138         { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
    139         { LDAP_ATTR_HOME_DRIVE,         "sambaHomeDrive"        },
    140         { LDAP_ATTR_HOME_PATH,          "sambaHomePath"         },
    141         { LDAP_ATTR_LOGON_SCRIPT,       "sambaLogonScript"      },
    142         { LDAP_ATTR_PROFILE_PATH,       "sambaProfilePath"      },
    143         { LDAP_ATTR_USER_WKS,           "sambaUserWorkstations" },
    144         { LDAP_ATTR_USER_SID,           LDAP_ATTRIBUTE_SID      },
    145         { LDAP_ATTR_PRIMARY_GROUP_SID,  "sambaPrimaryGroupSID"  },
    146         { LDAP_ATTR_LMPW,               "sambaLMPassword"       },
    147         { LDAP_ATTR_NTPW,               "sambaNTPassword"       },
    148         { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
    149         { LDAP_ATTR_ACB_INFO,           "sambaAcctFlags"        },
    150         { LDAP_ATTR_MUNGED_DIAL,        "sambaMungedDial"       },
    151         { LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
    152         { LDAP_ATTR_BAD_PASSWORD_TIME,  "sambaBadPasswordTime"  },
    153         { LDAP_ATTR_PWD_HISTORY,        "sambaPasswordHistory"  },
    154         { LDAP_ATTR_LOGON_HOURS,        "sambaLogonHours"       },
    155         { LDAP_ATTR_LIST_END,           NULL                    }
    156 };
    157 
    158 /* attributes used for allocating RIDs */
    159 
    160 ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
    161         { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
    162         { LDAP_ATTR_NEXT_RID,           "sambaNextRid"          },
    163         { LDAP_ATTR_NEXT_USERRID,       "sambaNextUserRid"      },
    164         { LDAP_ATTR_NEXT_GROUPRID,      "sambaNextGroupRid"     },
    165         { LDAP_ATTR_DOM_SID,            LDAP_ATTRIBUTE_SID      },
    166         { LDAP_ATTR_ALGORITHMIC_RID_BASE,"sambaAlgorithmicRidBase"},
    167         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
    168         { LDAP_ATTR_LIST_END,           NULL                    },
    169 };
    170 
    171 /* Samba 3.0 group mapping attributes */
    172 
    173 ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
    174         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
    175         { LDAP_ATTR_GROUP_SID,          LDAP_ATTRIBUTE_SID      },
    176         { LDAP_ATTR_GROUP_TYPE,         "sambaGroupType"        },
    177         { LDAP_ATTR_SID_LIST,           "sambaSIDList"          },
    178         { LDAP_ATTR_DESC,               "description"           },
    179         { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
    180         { LDAP_ATTR_CN,                 "cn"                    },
    181         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
    182         { LDAP_ATTR_LIST_END,           NULL                    }       
    183 };
    184 
    185 ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
    186         { LDAP_ATTR_GROUP_SID,          LDAP_ATTRIBUTE_SID      },
    187         { LDAP_ATTR_GROUP_TYPE,         "sambaGroupType"        },
    188         { LDAP_ATTR_DESC,               "description"           },
    189         { LDAP_ATTR_DISPLAY_NAME,       "displayName"           },
    190         { LDAP_ATTR_SID_LIST,           "sambaSIDList"          },
    191         { LDAP_ATTR_LIST_END,           NULL                    }       
    192 };
    193 
    194 /* idmap_ldap sambaUnixIdPool */
    195 
    196 ATTRIB_MAP_ENTRY idpool_attr_list[] = {
    197         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
    198         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
    199         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
    200         { LDAP_ATTR_LIST_END,           NULL                    }       
    201 };
    202 
    203 ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
    204         { LDAP_ATTR_SID,                LDAP_ATTRIBUTE_SID      },
    205         { LDAP_ATTR_UIDNUMBER,          LDAP_ATTRIBUTE_UIDNUMBER},
    206         { LDAP_ATTR_GIDNUMBER,          LDAP_ATTRIBUTE_GIDNUMBER},
    207         { LDAP_ATTR_OBJCLASS,           "objectClass"           },
    208         { LDAP_ATTR_LIST_END,           NULL                    }       
    209 };
    210 
    211 /**********************************************************************
    212  perform a simple table lookup and return the attribute name
    213  **********************************************************************/
    214  
    215  const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
    216 {
    217         int i = 0;
    218 
    219         while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
    220                 if ( table[i].attrib == key )
    221                         return table[i].name;
    222                 i++;
    223         }
    224 
    225         return NULL;
    226 }
    227 
    228 
    229 /**********************************************************************
    230  Return the list of attribute names from a mapping table
    231  **********************************************************************/
    232 
    233  const char** get_attr_list( TALLOC_CTX *mem_ctx, ATTRIB_MAP_ENTRY table[] )
    234 {
    235         const char **names;
    236         int i = 0;
    237 
    238         while ( table[i].attrib != LDAP_ATTR_LIST_END )
    239                 i++;
    240         i++;
    241 
    242         names = TALLOC_ARRAY( mem_ctx, const char*, i );
    243         if ( !names ) {
    244                 DEBUG(0,("get_attr_list: out of memory\n"));
    245                 return NULL;
    246         }
    247 
    248         i = 0;
    249         while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
    250                 names[i] = talloc_strdup( names, table[i].name );
    251                 i++;
    252         }
    253         names[i] = NULL;
    254 
    255         return names;
    256 }
    25738
    25839/*******************************************************************
     
    26546{
    26647        char **values;
     48        size_t size = 0;
    26749
    26850        if ( !attribute )
     
    27759        }
    27860
    279         if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, False) == (size_t)-1) {
     61        if (!convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, &size)) {
    28062                DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
    28163                          attribute, values[0]));
     
    405187                }
    406188
    407                 if (StrCaseCmp(tmp, result) < 0) {
     189                if (strcasecmp_m(tmp, result) < 0) {
    408190                        TALLOC_FREE(result);
    409191                        result = tmp;
     
    456238                return false;
    457239        }
    458         ret = sid_parse((char *)blob.data, blob.length, sid);
     240        ret = sid_parse(blob.data, blob.length, sid);
    459241        TALLOC_FREE(blob.data);
    460242        return ret;
     
    466248}
    467249
    468  void talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result)
     250 void smbldap_talloc_autofree_ldapmsg(TALLOC_CTX *mem_ctx, LDAPMessage *result)
    469251{
    470252        LDAPMessage **handle;
     
    474256        }
    475257
    476         handle = TALLOC_P(mem_ctx, LDAPMessage *);
     258        handle = talloc(mem_ctx, LDAPMessage *);
    477259        SMB_ASSERT(handle != NULL);
    478260
     
    486268}
    487269
    488  void talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod)
     270 void smbldap_talloc_autofree_ldapmod(TALLOC_CTX *mem_ctx, LDAPMod **mod)
    489271{
    490272        LDAPMod ***handle;
     
    494276        }
    495277
    496         handle = TALLOC_P(mem_ctx, LDAPMod **);
     278        handle = talloc(mem_ctx, LDAPMod **);
    497279        SMB_ASSERT(handle != NULL);
    498280
     
    520302        }
    521303
    522 #if 0   /* commented out after discussion with abartlet.  Do not reenable.
     304#if 0   /* commented out after discussion with abartlet.  Do not re-enable.
    523305           left here so other do not re-add similar code   --jerry */
    524306        if (value == NULL || *value == '\0')
     
    572354                SMB_ASSERT(mods[i]->mod_bvalues[j] != NULL);
    573355
    574                 mods[i]->mod_bvalues[j]->bv_val = (char *)memdup(blob->data, blob->length);
     356                mods[i]->mod_bvalues[j]->bv_val = (char *)smb_memdup(blob->data, blob->length);
    575357                SMB_ASSERT(mods[i]->mod_bvalues[j]->bv_val != NULL);
    576358                mods[i]->mod_bvalues[j]->bv_len = blob->length;
     
    630412        bool existed;
    631413        DATA_BLOB oldblob = data_blob_null;
    632 
    633         if (attribute == NULL) {
    634                 /* This can actually happen for ldapsam_compat where we for
    635                  * example don't have a password history */
    636                 return;
    637         }
    638414
    639415        if (existing != NULL) {
     
    654430                } else {
    655431                        /* all of our string attributes are case insensitive */
    656                         equal = (newval && (StrCaseCmp(oldval, newval) == 0));
     432                        equal = (newval && (strcasecmp_m(oldval, newval) == 0));
    657433                }
    658434
     
    770546        ZERO_STRUCTP(t);
    771547
    772         DLIST_ADD_END(smbldap_state_lookup_list, t, struct smbldap_state_lookup *);
     548        DLIST_ADD_END(smbldap_state_lookup_list, t);
    773549        t->ld = ld;
    774550        t->smbldap_state = smbldap_state;
     
    779555*******************************************************************/
    780556
    781 int smb_ldap_start_tls(LDAP *ldap_struct, int version)
     557int smbldap_start_tls(LDAP *ldap_struct, int version)
    782558{
    783559#ifdef LDAP_OPT_X_TLS
     
    950726 ******************************************************************/
    951727
    952 int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri)
     728int smbldap_setup_full_conn(LDAP **ldap_struct, const char *uri)
    953729{
    954730        int rc, version;
     
    964740        }
    965741
    966         rc = smb_ldap_start_tls(*ldap_struct, version);
     742        rc = smbldap_start_tls(*ldap_struct, version);
    967743        if (rc) {
    968744                return rc;
     
    1001777        /* Start TLS if required */
    1002778
    1003         rc = smb_ldap_start_tls(*ldap_struct, version);
     779        rc = smbldap_start_tls(*ldap_struct, version);
    1004780        if (rc) {
    1005781                return rc;
     
    1095871
    1096872        smb_ldap_upgrade_conn(ldap_struct, &version);
    1097         smb_ldap_start_tls(ldap_struct, version);
     873        smbldap_start_tls(ldap_struct, version);
    1098874
    1099875        /** @TODO Should we be doing something to check what servers we rebind to?
     
    1171947        int rc;
    1172948        int version;
    1173 
    1174         if (!ldap_state->anonymous && !ldap_state->bind_dn) {
    1175                 char *bind_dn = NULL;
    1176                 char *bind_secret = NULL;
    1177 
    1178                 /* get the default dn and password only if they are not set already */
    1179                 if (!fetch_ldap_pw(&bind_dn, &bind_secret)) {
    1180                         DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
    1181                         rc = LDAP_INVALID_CREDENTIALS;
    1182                         goto done;
    1183                 }
    1184                 smbldap_set_creds(ldap_state, false, bind_dn, bind_secret);
    1185                 SAFE_FREE(bind_dn);
    1186                 memset(bind_secret, '\0', strlen(bind_secret));
    1187                 SAFE_FREE(bind_secret);
    1188         }
    1189949
    1190950        /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
     
    1212972#endif
    1213973
    1214         rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
     974        /* When there is an alternative bind callback is set,
     975           attempt to use it to perform the bind */
     976        if (ldap_state->bind_callback != NULL) {
     977                /* We have to allow bind callback to be run under become_root/unbecome_root
     978                   to make sure within smbd the callback has proper write access to its resources,
     979                   like credential cache. This is similar to passdb case where this callback is supposed
     980                   to be used. When used outside smbd, become_root()/unbecome_root() are no-op.
     981                */
     982                become_root();
     983                rc = ldap_state->bind_callback(ldap_struct, ldap_state, ldap_state->bind_callback_data);
     984                unbecome_root();
     985        } else {
     986                rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
     987        }
    1215988
    1216989        if (rc != LDAP_SUCCESS) {
     
    12491022}
    12501023
    1251 static void smbldap_idle_fn(struct event_context *event_ctx,
    1252                             struct timed_event *te,
     1024static void smbldap_idle_fn(struct tevent_context *tevent_ctx,
     1025                            struct tevent_timer *te,
    12531026                            struct timeval now_abs,
    12541027                            void *private_data);
     
    13061079
    13071080        ldap_state->last_ping = time_mono(NULL);
    1308         ldap_state->pid = sys_getpid();
     1081        ldap_state->pid = getpid();
    13091082
    13101083        TALLOC_FREE(ldap_state->idle_event);
    13111084
    1312         if (ldap_state->event_context != NULL) {
    1313                 ldap_state->idle_event = event_add_timed(
    1314                         ldap_state->event_context, ldap_state,
     1085        if (ldap_state->tevent_context != NULL) {
     1086                ldap_state->idle_event = tevent_add_timer(
     1087                        ldap_state->tevent_context, ldap_state,
    13151088                        timeval_current_ofs(SMBLDAP_IDLE_TIME, 0),
    13161089                        smbldap_idle_fn, ldap_state);
     
    13451118}
    13461119
    1347 static bool got_alarm;
    1348 
    1349 static void (*old_handler)(int);
     1120static SIG_ATOMIC_T got_alarm;
    13501121
    13511122static void gotalarm_sig(int dummy)
    13521123{
    1353         got_alarm = True;
    1354 }
    1355 
    1356 static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
    1357                             int *attempts, time_t endtime)
     1124        got_alarm = 1;
     1125}
     1126
     1127static time_t calc_ldap_abs_endtime(int ldap_to)
     1128{
     1129        if (ldap_to == 0) {
     1130                /* No timeout - don't
     1131                   return a value for
     1132                   the alarm. */
     1133                return (time_t)0;
     1134        }
     1135
     1136        /* Make the alarm time one second beyond
     1137           the timout we're setting for the
     1138           remote search timeout, to allow that
     1139           to fire in preference. */
     1140
     1141        return time_mono(NULL)+ldap_to+1;
     1142}
     1143
     1144static int end_ldap_local_alarm(time_t absolute_endtime, int rc)
     1145{
     1146        if (absolute_endtime) {
     1147                alarm(0);
     1148                CatchSignal(SIGALRM, SIG_IGN);
     1149                if (got_alarm) {
     1150                        /* Client timeout error code. */
     1151                        got_alarm = 0;
     1152                        return LDAP_TIMEOUT;
     1153                }
     1154        }
     1155        return rc;
     1156}
     1157
     1158static void setup_ldap_local_alarm(struct smbldap_state *ldap_state, time_t absolute_endtime)
    13581159{
    13591160        time_t now = time_mono(NULL);
    1360         int open_rc = LDAP_SERVER_DOWN;
    1361 
    1362         if (*rc != LDAP_SERVER_DOWN)
    1363                 goto no_next;
    1364 
    1365         if (now >= endtime) {
     1161
     1162        if (absolute_endtime) {
     1163                got_alarm = 0;
     1164                CatchSignal(SIGALRM, gotalarm_sig);
     1165                alarm(absolute_endtime - now);
     1166        }
     1167
     1168        if (ldap_state->pid != getpid()) {
    13661169                smbldap_close(ldap_state);
    1367                 *rc = LDAP_TIMEOUT;
    1368                 goto no_next;
    1369         }
    1370 
    1371         if (*attempts == 0) {
    1372                 got_alarm = False;
    1373                 old_handler = CatchSignal(SIGALRM, gotalarm_sig);
    1374                 alarm(endtime - now);
    1375 
    1376                 if (ldap_state->pid != sys_getpid())
     1170        }
     1171}
     1172
     1173static void get_ldap_errs(struct smbldap_state *ldap_state, char **pp_ld_error, int *p_ld_errno)
     1174{
     1175        ldap_get_option(ldap_state->ldap_struct,
     1176                        LDAP_OPT_ERROR_NUMBER, p_ld_errno);
     1177
     1178        ldap_get_option(ldap_state->ldap_struct,
     1179                        LDAP_OPT_ERROR_STRING, pp_ld_error);
     1180}
     1181
     1182static int get_cached_ldap_connect(struct smbldap_state *ldap_state, time_t abs_endtime)
     1183{
     1184        int attempts = 0;
     1185
     1186        while (1) {
     1187                int rc;
     1188                time_t now;
     1189
     1190                now = time_mono(NULL);
     1191                ldap_state->last_use = now;
     1192
     1193                if (abs_endtime && now > abs_endtime) {
    13771194                        smbldap_close(ldap_state);
    1378         }
    1379 
    1380         while (1) {
    1381 
    1382                 if (*attempts != 0)
    1383                         smb_msleep(1000);
    1384 
    1385                 *attempts += 1;
    1386 
    1387                 open_rc = smbldap_open(ldap_state);
    1388 
    1389                 if (open_rc == LDAP_SUCCESS) {
    1390                         ldap_state->last_use = now;
    1391                         return True;
    1392                 }
    1393 
    1394                 if (open_rc == LDAP_INSUFFICIENT_ACCESS) {
     1195                        return LDAP_TIMEOUT;
     1196                }
     1197
     1198                rc = smbldap_open(ldap_state);
     1199
     1200                if (rc == LDAP_SUCCESS) {
     1201                        return LDAP_SUCCESS;
     1202                }
     1203
     1204                attempts++;
     1205                DEBUG(1, ("Connection to LDAP server failed for the "
     1206                        "%d try!\n", attempts));
     1207
     1208                if (rc == LDAP_INSUFFICIENT_ACCESS) {
    13951209                        /* The fact that we are non-root or any other
    13961210                         * access-denied condition will not change in the next
    13971211                         * round of trying */
    1398                         *rc = open_rc;
    1399                         break;
     1212                        return rc;
    14001213                }
    14011214
    14021215                if (got_alarm) {
    1403                         *rc = LDAP_TIMEOUT;
    1404                         break;
    1405                 }
    1406 
    1407                 if (open_rc != LDAP_SUCCESS) {
    1408                         DEBUG(1, ("Connection to LDAP server failed for the "
    1409                                   "%d try!\n", *attempts));
    1410                 }
    1411         }
    1412 
    1413  no_next:
    1414         CatchSignal(SIGALRM, old_handler);
    1415         alarm(0);
    1416         ldap_state->last_use = now;
    1417         return False;
     1216                        smbldap_close(ldap_state);
     1217                        return LDAP_TIMEOUT;
     1218                }
     1219
     1220                smb_msleep(1000);
     1221
     1222                if (got_alarm) {
     1223                        smbldap_close(ldap_state);
     1224                        return LDAP_TIMEOUT;
     1225                }
     1226        }
    14181227}
    14191228
     
    14281237{
    14291238        int             rc = LDAP_SERVER_DOWN;
    1430         int             attempts = 0;
    14311239        char           *utf8_filter;
    1432         time_t          endtime = time_mono(NULL)+lp_ldap_timeout();
     1240        int             to = lp_ldap_timeout();
     1241        time_t          abs_endtime = calc_ldap_abs_endtime(to);
    14331242        struct          timeval timeout;
     1243        struct          timeval *timeout_ptr = NULL;
    14341244        size_t          converted_size;
    14351245
     
    14681278        }
    14691279
    1470         /* Setup timeout for the ldap_search_ext_s call - local and remote. */
    1471         timeout.tv_sec = lp_ldap_timeout();
    1472         timeout.tv_usec = 0;
    1473 
    1474         /* Setup alarm timeout.... Do we need both of these ? JRA.
    1475          * Yes, I think we do need both of these. The server timeout only
    1476          * covers the case where the server's operation takes too long. It
    1477          * does not cover the case where the request hangs on its way to the
    1478          * server. The server side timeout is not strictly necessary, it's
    1479          * just a bit more kind to the server. VL. */
    1480 
    1481         got_alarm = 0;
    1482         CatchSignal(SIGALRM, gotalarm_sig);
    1483         alarm(lp_ldap_timeout());
    1484         /* End setup timeout. */
    1485 
    1486         while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
     1280        /* Setup remote timeout for the ldap_search_ext_s call. */
     1281        if (to) {
     1282                timeout.tv_sec = to;
     1283                timeout.tv_usec = 0;
     1284                timeout_ptr = &timeout;
     1285        }
     1286
     1287        setup_ldap_local_alarm(ldap_state, abs_endtime);
     1288
     1289        while (1) {
     1290                char *ld_error = NULL;
     1291                int ld_errno;
     1292
     1293                rc = get_cached_ldap_connect(ldap_state, abs_endtime);
     1294                if (rc != LDAP_SUCCESS) {
     1295                        break;
     1296                }
     1297
    14871298                rc = ldap_search_ext_s(ldap_state->ldap_struct, base, scope,
    14881299                                       utf8_filter,
    1489                                        CONST_DISCARD(char **, attrs),
    1490                                        attrsonly, sctrls, cctrls, &timeout,
     1300                                       discard_const_p(char *, attrs),
     1301                                       attrsonly, sctrls, cctrls, timeout_ptr,
    14911302                                       sizelimit, res);
    1492                 if (rc != LDAP_SUCCESS) {
    1493                         char *ld_error = NULL;
    1494                         int ld_errno;
    1495 
    1496                         ldap_get_option(ldap_state->ldap_struct,
    1497                                         LDAP_OPT_ERROR_NUMBER, &ld_errno);
    1498 
    1499                         ldap_get_option(ldap_state->ldap_struct,
    1500                                         LDAP_OPT_ERROR_STRING, &ld_error);
    1501                         DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
    1502                                    "(%s)\n", base, ld_errno,
    1503                                    ldap_err2string(rc),
    1504                                    ld_error ? ld_error : "unknown"));
    1505                         SAFE_FREE(ld_error);
    1506 
    1507                         if (ld_errno == LDAP_SERVER_DOWN) {
    1508                                 ldap_unbind(ldap_state->ldap_struct);
    1509                                 ldap_state->ldap_struct = NULL;
    1510                         }
    1511                 }
     1303                if (rc == LDAP_SUCCESS) {
     1304                        break;
     1305                }
     1306
     1307                get_ldap_errs(ldap_state, &ld_error, &ld_errno);
     1308
     1309                DEBUG(10, ("Failed search for base: %s, error: %d (%s) "
     1310                           "(%s)\n", base, ld_errno,
     1311                           ldap_err2string(rc),
     1312                           ld_error ? ld_error : "unknown"));
     1313                SAFE_FREE(ld_error);
     1314
     1315                if (ld_errno != LDAP_SERVER_DOWN) {
     1316                        break;
     1317                }
     1318                ldap_unbind(ldap_state->ldap_struct);
     1319                ldap_state->ldap_struct = NULL;
    15121320        }
    15131321
    15141322        TALLOC_FREE(utf8_filter);
    1515 
    1516         /* Teardown timeout. */
    1517         CatchSignal(SIGALRM, SIG_IGN);
    1518         alarm(0);
    1519 
    1520         if (got_alarm != 0)
    1521                 return LDAP_TIMELIMIT_EXCEEDED;
    1522 
    1523         return rc;
     1323        return end_ldap_local_alarm(abs_endtime, rc);
    15241324}
    15251325
     
    15691369        ber_flatten(cookie_be, &cookie_bv);
    15701370
    1571         pr.ldctl_oid = CONST_DISCARD(char *, ADS_PAGE_CTL_OID);
     1371        pr.ldctl_oid = discard_const_p(char, ADS_PAGE_CTL_OID);
    15721372        pr.ldctl_iscritical = (char) critical;
    15731373        pr.ldctl_value.bv_len = cookie_bv->bv_len;
     
    16271427{
    16281428        int             rc = LDAP_SERVER_DOWN;
    1629         int             attempts = 0;
    16301429        char           *utf8_dn;
    1631         time_t          endtime = time_mono(NULL)+lp_ldap_timeout();
     1430        time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
    16321431        size_t          converted_size;
    16331432
     
    16401439        }
    16411440
    1642         while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
     1441        setup_ldap_local_alarm(ldap_state, abs_endtime);
     1442
     1443        while (1) {
     1444                char *ld_error = NULL;
     1445                int ld_errno;
     1446
     1447                rc = get_cached_ldap_connect(ldap_state, abs_endtime);
     1448                if (rc != LDAP_SUCCESS) {
     1449                        break;
     1450                }
     1451
    16431452                rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
    1644                 if (rc != LDAP_SUCCESS) {
    1645                         char *ld_error = NULL;
    1646                         int ld_errno;
    1647 
    1648                         ldap_get_option(ldap_state->ldap_struct,
    1649                                         LDAP_OPT_ERROR_NUMBER, &ld_errno);
    1650 
    1651                         ldap_get_option(ldap_state->ldap_struct,
    1652                                         LDAP_OPT_ERROR_STRING, &ld_error);
    1653                         DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
    1654                                    "(%s)\n", dn, ld_errno,
    1655                                    ldap_err2string(rc),
    1656                                    ld_error ? ld_error : "unknown"));
    1657                         SAFE_FREE(ld_error);
    1658 
    1659                         if (ld_errno == LDAP_SERVER_DOWN) {
    1660                                 ldap_unbind(ldap_state->ldap_struct);
    1661                                 ldap_state->ldap_struct = NULL;
    1662                         }
    1663                 }
     1453                if (rc == LDAP_SUCCESS) {
     1454                        break;
     1455                }
     1456
     1457                get_ldap_errs(ldap_state, &ld_error, &ld_errno);
     1458
     1459                DEBUG(10, ("Failed to modify dn: %s, error: %d (%s) "
     1460                           "(%s)\n", dn, ld_errno,
     1461                           ldap_err2string(rc),
     1462                           ld_error ? ld_error : "unknown"));
     1463                SAFE_FREE(ld_error);
     1464
     1465                if (ld_errno != LDAP_SERVER_DOWN) {
     1466                        break;
     1467                }
     1468                ldap_unbind(ldap_state->ldap_struct);
     1469                ldap_state->ldap_struct = NULL;
    16641470        }
    16651471
    16661472        TALLOC_FREE(utf8_dn);
    1667         return rc;
     1473        return end_ldap_local_alarm(abs_endtime, rc);
    16681474}
    16691475
     
    16711477{
    16721478        int             rc = LDAP_SERVER_DOWN;
    1673         int             attempts = 0;
    16741479        char           *utf8_dn;
    1675         time_t          endtime = time_mono(NULL)+lp_ldap_timeout();
     1480        time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
    16761481        size_t          converted_size;
    16771482
     
    16841489        }
    16851490
    1686         while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
     1491        setup_ldap_local_alarm(ldap_state, abs_endtime);
     1492
     1493        while (1) {
     1494                char *ld_error = NULL;
     1495                int ld_errno;
     1496
     1497                rc = get_cached_ldap_connect(ldap_state, abs_endtime);
     1498                if (rc != LDAP_SUCCESS) {
     1499                        break;
     1500                }
     1501
    16871502                rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
    1688                 if (rc != LDAP_SUCCESS) {
    1689                         char *ld_error = NULL;
    1690                         int ld_errno;
    1691 
    1692                         ldap_get_option(ldap_state->ldap_struct,
    1693                                         LDAP_OPT_ERROR_NUMBER, &ld_errno);
    1694 
    1695                         ldap_get_option(ldap_state->ldap_struct,
    1696                                         LDAP_OPT_ERROR_STRING, &ld_error);
    1697                         DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
    1698                                    "(%s)\n", dn, ld_errno,
    1699                                    ldap_err2string(rc),
    1700                                    ld_error ? ld_error : "unknown"));
    1701                         SAFE_FREE(ld_error);
    1702 
    1703                         if (ld_errno == LDAP_SERVER_DOWN) {
    1704                                 ldap_unbind(ldap_state->ldap_struct);
    1705                                 ldap_state->ldap_struct = NULL;
    1706                         }
    1707                 }
     1503                if (rc == LDAP_SUCCESS) {
     1504                        break;
     1505                }
     1506
     1507                get_ldap_errs(ldap_state, &ld_error, &ld_errno);
     1508
     1509                DEBUG(10, ("Failed to add dn: %s, error: %d (%s) "
     1510                           "(%s)\n", dn, ld_errno,
     1511                           ldap_err2string(rc),
     1512                           ld_error ? ld_error : "unknown"));
     1513                SAFE_FREE(ld_error);
     1514
     1515                if (ld_errno != LDAP_SERVER_DOWN) {
     1516                        break;
     1517                }
     1518                ldap_unbind(ldap_state->ldap_struct);
     1519                ldap_state->ldap_struct = NULL;
    17081520        }
    17091521
    17101522        TALLOC_FREE(utf8_dn);
    1711         return rc;
     1523        return end_ldap_local_alarm(abs_endtime, rc);
    17121524}
    17131525
     
    17151527{
    17161528        int             rc = LDAP_SERVER_DOWN;
    1717         int             attempts = 0;
    17181529        char           *utf8_dn;
    1719         time_t          endtime = time_mono(NULL)+lp_ldap_timeout();
     1530        time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
    17201531        size_t          converted_size;
    17211532
     
    17281539        }
    17291540
    1730         while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
     1541        setup_ldap_local_alarm(ldap_state, abs_endtime);
     1542
     1543        while (1) {
     1544                char *ld_error = NULL;
     1545                int ld_errno;
     1546
     1547                rc = get_cached_ldap_connect(ldap_state, abs_endtime);
     1548                if (rc != LDAP_SUCCESS) {
     1549                        break;
     1550                }
     1551
    17311552                rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
    1732                 if (rc != LDAP_SUCCESS) {
    1733                         char *ld_error = NULL;
    1734                         int ld_errno;
    1735 
    1736                         ldap_get_option(ldap_state->ldap_struct,
    1737                                         LDAP_OPT_ERROR_NUMBER, &ld_errno);
    1738 
    1739                         ldap_get_option(ldap_state->ldap_struct,
    1740                                         LDAP_OPT_ERROR_STRING, &ld_error);
    1741                         DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
    1742                                    "(%s)\n", dn, ld_errno,
    1743                                    ldap_err2string(rc),
    1744                                    ld_error ? ld_error : "unknown"));
    1745                         SAFE_FREE(ld_error);
    1746 
    1747                         if (ld_errno == LDAP_SERVER_DOWN) {
    1748                                 ldap_unbind(ldap_state->ldap_struct);
    1749                                 ldap_state->ldap_struct = NULL;
    1750                         }
    1751                 }
     1553                if (rc == LDAP_SUCCESS) {
     1554                        break;
     1555                }
     1556
     1557                get_ldap_errs(ldap_state, &ld_error, &ld_errno);
     1558
     1559                DEBUG(10, ("Failed to delete dn: %s, error: %d (%s) "
     1560                           "(%s)\n", dn, ld_errno,
     1561                           ldap_err2string(rc),
     1562                           ld_error ? ld_error : "unknown"));
     1563                SAFE_FREE(ld_error);
     1564
     1565                if (ld_errno != LDAP_SERVER_DOWN) {
     1566                        break;
     1567                }
     1568                ldap_unbind(ldap_state->ldap_struct);
     1569                ldap_state->ldap_struct = NULL;
    17521570        }
    17531571
    17541572        TALLOC_FREE(utf8_dn);
    1755         return rc;
     1573        return end_ldap_local_alarm(abs_endtime, rc);
    17561574}
    17571575
     
    17621580{
    17631581        int             rc = LDAP_SERVER_DOWN;
    1764         int             attempts = 0;
    1765         time_t          endtime = time_mono(NULL)+lp_ldap_timeout();
     1582        time_t          abs_endtime = calc_ldap_abs_endtime(lp_ldap_timeout());
    17661583
    17671584        if (!ldap_state)
    17681585                return (-1);
    17691586
    1770         while (another_ldap_try(ldap_state, &rc, &attempts, endtime)) {
     1587        setup_ldap_local_alarm(ldap_state, abs_endtime);
     1588
     1589        while (1) {
     1590                char *ld_error = NULL;
     1591                int ld_errno;
     1592
     1593                rc = get_cached_ldap_connect(ldap_state, abs_endtime);
     1594                if (rc != LDAP_SUCCESS) {
     1595                        break;
     1596                }
     1597
    17711598                rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid,
    17721599                                               reqdata, serverctrls,
    17731600                                               clientctrls, retoidp, retdatap);
    1774                 if (rc != LDAP_SUCCESS) {
    1775                         char *ld_error = NULL;
    1776                         int ld_errno;
    1777 
    1778                         ldap_get_option(ldap_state->ldap_struct,
    1779                                         LDAP_OPT_ERROR_NUMBER, &ld_errno);
    1780 
    1781                         ldap_get_option(ldap_state->ldap_struct,
    1782                                         LDAP_OPT_ERROR_STRING, &ld_error);
    1783                         DEBUG(10, ("Extended operation failed with error: "
    1784                                    "%d (%s) (%s)\n", ld_errno,
    1785                                    ldap_err2string(rc),
    1786                                    ld_error ? ld_error : "unknown"));
    1787                         SAFE_FREE(ld_error);
    1788 
    1789                         if (ld_errno == LDAP_SERVER_DOWN) {
    1790                                 ldap_unbind(ldap_state->ldap_struct);
    1791                                 ldap_state->ldap_struct = NULL;
    1792                         }
    1793                 }
    1794         }
    1795 
    1796         return rc;
     1601                if (rc == LDAP_SUCCESS) {
     1602                        break;
     1603                }
     1604
     1605                get_ldap_errs(ldap_state, &ld_error, &ld_errno);
     1606
     1607                DEBUG(10, ("Extended operation failed with error: "
     1608                           "%d (%s) (%s)\n", ld_errno,
     1609                           ldap_err2string(rc),
     1610                           ld_error ? ld_error : "unknown"));
     1611                SAFE_FREE(ld_error);
     1612
     1613                if (ld_errno != LDAP_SERVER_DOWN) {
     1614                        break;
     1615                }
     1616                ldap_unbind(ldap_state->ldap_struct);
     1617                ldap_state->ldap_struct = NULL;
     1618        }
     1619
     1620        return end_ldap_local_alarm(abs_endtime, rc);
    17971621}
    17981622
     
    18041628                           LDAPMessage ** result)
    18051629{
    1806         return smbldap_search(ldap_state, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE,
     1630        return smbldap_search(ldap_state, lp_ldap_suffix(talloc_tos()),
     1631                              LDAP_SCOPE_SUBTREE,
    18071632                              filter, search_attr, 0, result);
    18081633}
    18091634
    1810 static void smbldap_idle_fn(struct event_context *event_ctx,
    1811                             struct timed_event *te,
     1635static void smbldap_idle_fn(struct tevent_context *tevent_ctx,
     1636                            struct tevent_timer *te,
    18121637                            struct timeval now_abs,
    18131638                            void *private_data)
     
    18261651
    18271652                /* this needs to be made monotonic clock aware inside tevent: */
    1828                 state->idle_event = event_add_timed(
    1829                         event_ctx, state,
     1653                state->idle_event = tevent_add_timer(
     1654                        tevent_ctx, state,
    18301655                        timeval_add(&now_abs, SMBLDAP_IDLE_TIME, 0),
    18311656                        smbldap_idle_fn,
     
    18521677        SAFE_FREE((*ldap_state)->bind_dn);
    18531678        SAFE_FREE((*ldap_state)->bind_secret);
     1679        (*ldap_state)->bind_callback = NULL;
     1680        (*ldap_state)->bind_callback_data = NULL;
    18541681
    18551682        TALLOC_FREE(*ldap_state);
     
    18691696 *********************************************************************/
    18701697
    1871 NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx,
     1698NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct tevent_context *tevent_ctx,
    18721699                      const char *location,
     1700                      bool anon,
     1701                      const char *bind_dn,
     1702                      const char *bind_secret,
    18731703                      struct smbldap_state **smbldap_state)
    18741704{
    1875         *smbldap_state = TALLOC_ZERO_P(mem_ctx, struct smbldap_state);
     1705        *smbldap_state = talloc_zero(mem_ctx, struct smbldap_state);
    18761706        if (!*smbldap_state) {
    18771707                DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
     
    18851715        }
    18861716
    1887         (*smbldap_state)->event_context = event_ctx;
     1717        (*smbldap_state)->tevent_context = tevent_ctx;
     1718
     1719        if (bind_dn && bind_secret) {
     1720                smbldap_set_creds(*smbldap_state, anon, bind_dn, bind_secret);
     1721        }
    18881722
    18891723        talloc_set_destructor(*smbldap_state, smbldap_state_destructor);
     
    19361770
    19371771        rc = ldap_search_s(ld, "", LDAP_SCOPE_BASE,
    1938                            "(objectclass=*)", CONST_DISCARD(char **, attrs), 0 , &msg);
     1772                           "(objectclass=*)", discard_const_p(char *, attrs), 0 , &msg);
    19391773
    19401774        if (rc != LDAP_SUCCESS) {
     
    20241858
    20251859        SAFE_FREE(ldap_state->bind_dn);
     1860        ldap_state->bind_callback = NULL;
     1861        ldap_state->bind_callback_data = NULL;
     1862
    20261863        if (ldap_state->bind_secret) {
    20271864                /* make sure secrets are zeroed out of memory */
Note: See TracChangeset for help on using the changeset viewer.