Projet

Général

Profil

Paste
Télécharger (12,6 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ldap / ldap_query / LdapQuery.class.php @ 91af538d

1
<?php
2

    
3
/**
4
 * @file
5
 * Defines server classes and related functions.
6
 */
7

    
8
/**
9
 * LDAP Server Class.
10
 *
11
 *  This class is used to create, work with, and eventually destroy ldap_server
12
 * objects.
13
 *
14
 * @todo make bindpw protected
15
 */
16
class LdapQuery {
17
  /**
18
   * LDAP Settings.
19
   */
20
  public $query_numeric_id;
21
  public $qid;
22
  public $name;
23
  public $sid;
24
  public $status;
25

    
26
  public $baseDn = [];
27
  public $base_dn_str = NULL;
28
  public $filter;
29
  public $attributes_str = NULL;
30
  public $attributes = [];
31

    
32
  public $sizelimit = 0;
33
  public $timelimit = 0;
34
  public $deref = LDAP_DEREF_NEVER;
35
  public $scope = LDAP_SCOPE_SUBTREE;
36

    
37

    
38
  public $inDatabase = FALSE;
39
  public $detailedWatchdogLog = FALSE;
40

    
41
  /**
42
   * Constructor Method.
43
   */
44
  public function __construct($qid) {
45
    if (!is_scalar($qid)) {
46
      return;
47
    }
48

    
49
    $query_records = [];
50
    if (module_exists('ctools')) {
51
      ctools_include('export');
52
      $result = ctools_export_load_object('ldap_query', 'names', [$qid]);
53
      if (isset($result[$qid])) {
54
        $query_record = $result[$qid];
55
        foreach ($query_record as $property_name => $value) {
56
          $this->{$property_name} = $value;
57
        }
58
      }
59
    }
60
    else {
61
      $select = db_select('ldap_query')
62
        ->fields('ldap_query')
63
        ->condition('ldap_query.qid', $qid)
64
        ->execute();
65
      foreach ($select as $record) {
66
        $query_records[$record->qid] = $record;
67
      }
68
      if (!isset($query_records[$qid])) {
69
        $this->inDatabase = FALSE;
70
        return;
71
      }
72
      $query_record = $query_records[$qid];
73
      foreach ($this->fields() as $field_id => $field) {
74
        if (isset($query_record->$field_id)) {
75
          $this->{$field['property_name']} = @$query_record->$field_id;
76
        }
77
      }
78
    }
79

    
80
    // Special properties that don't map directly from storage and defaults.
81
    $this->inDatabase = TRUE;
82
    $this->detailedWatchdogLog = variable_get('ldap_help_watchdog_detail', 0);
83

    
84
    $this->baseDn = $this->linesToArray($this->base_dn_str);
85
    $this->attributes = ($this->attributes_str) ? $this->csvToArray($this->attributes_str, TRUE) : [];
86

    
87
  }
88

    
89
  /**
90
   * Destructor Method.
91
   */
92
  public function __destruct() {
93

    
94
  }
95

    
96
  /**
97
   * Invoke Method.
98
   */
99
  public function __invoke() {
100

    
101
  }
102

    
103
  /**
104
   * Function search($base_dn = NULL, $filter, $attributes = array(), $attrsonly = 0, $sizelimit = 0, $timelimit = 0, $deref = LDAP_DEREF_NEVER) {.
105
   */
106
  public function query() {
107
    ldap_servers_module_load_include('php', 'ldap_servers', 'LdapServer.class');
108
    $ldap_server = new LdapServer($this->sid);
109
    $ldap_server->connect();
110
    $ldap_server->bind();
111
    $results = [];
112

    
113
    $count = 0;
114

    
115
    foreach ($this->baseDn as $base_dn) {
116
      $result = $ldap_server->search($base_dn, $this->filter, $this->attributes, 0, $this->sizelimit, $this->timelimit, $this->deref, $this->scope);
117
      if ($result !== FALSE && $result['count'] > 0) {
118
        $count = $count + $result['count'];
119
        $results = array_merge($results, $result);
120
      }
121
    }
122
    $results['count'] = $count;
123

    
124
    return $results;
125
  }
126

    
127
  /**
128
   * Error methods and properties.
129
   */
130

    
131
  protected $_errorMsg = NULL;
132
  protected $_hasError = FALSE;
133
  protected $_errorName = NULL;
134

    
135
  /**
136
   *
137
   */
138
  public function setError($_errorName, $_errorMsgText = NULL) {
139
    $this->_errorMsgText = $_errorMsgText;
140
    $this->_errorName = $_errorName;
141
    $this->_hasError = TRUE;
142
  }
143

    
144
  /**
145
   *
146
   */
147
  public function clearError() {
148
    $this->_hasError = FALSE;
149
    $this->_errorMsg = NULL;
150
    $this->_errorName = NULL;
151
  }
152

    
153
  /**
154
   *
155
   */
156
  public function hasError() {
157
    return ($this->_hasError || $this->ldapErrorNumber());
158
  }
159

    
160
  /**
161
   * @param null $type
162
   *
163
   * @return string|null
164
   */
165
  public function errorMsg($type = NULL) {
166
    if ($type == 'ldap' && $this->connection) {
167
      return ldap_err2str(ldap_errno($this->connection));
168
    }
169
    elseif ($type == NULL) {
170
      return $this->_errorMsg;
171
    }
172
    else {
173
      return NULL;
174
    }
175
  }
176

    
177
  /**
178
   * @param null $type
179
   *
180
   * @return string|null
181
   */
182
  public function errorName($type = NULL) {
183
    if ($type == 'ldap' && $this->connection) {
184
      return "LDAP Error: " . ldap_error($this->connection);
185
    }
186
    elseif ($type == NULL) {
187
      return $this->_errorName;
188
    }
189
    else {
190
      return NULL;
191
    }
192
  }
193

    
194
  /**
195
   *
196
   */
197
  public function ldapErrorNumber() {
198
    return FALSE;
199
  }
200

    
201
  /**
202
   *
203
   */
204
  protected function linesToArray($lines) {
205
    $lines = trim($lines);
206
    if ($lines) {
207
      $array = preg_split('/[\n\r]+/', $lines);
208
      foreach ($array as $i => $value) {
209
        $array[$i] = trim($value);
210
      }
211
    }
212
    else {
213
      $array = [];
214
    }
215
    return $array;
216
  }
217

    
218
  /**
219
   *
220
   */
221
  protected function csvToArray($string, $strip_quotes = FALSE) {
222
    $items = explode(',', $string);
223
    foreach ($items as $i => $item) {
224
      $items[$i] = trim($item);
225
      if ($strip_quotes) {
226
        $items[$i] = trim($items[$i], '"');
227
      }
228
    }
229
    return $items;
230
  }
231

    
232
  /**
233
   *
234
   */
235
  public static function fields() {
236
    $fields = [
237
      'query_numeric_id' => [
238
        'property_name' => 'query_numeric_id',
239
        'schema' => [
240
          'type' => 'serial',
241
          'unsigned' => TRUE,
242
          'not null' => TRUE,
243
          'description' => 'Primary ID field for the table.  Only used internally.',
244
          'no export' => TRUE,
245
        ],
246
      ],
247

    
248
      'qid' => [
249
        'property_name' => 'qid',
250
        'schema' => [
251
          'type' => 'varchar',
252
          'length' => 20,
253
          'description' => 'Machine name for query.',
254
          'not null' => TRUE,
255
        ],
256
        'form' => [
257
          'field_group' => 'basic',
258
          '#type' => 'textfield',
259
          '#title' => t('Machine name for this query configuration.'),
260
          '#size' => 20,
261
          '#maxlength' => 20,
262
          '#description' => t('May only contain alphanumeric characters (a-z, A-Z, 0-9, and _)'),
263
          '#required' => TRUE,
264
        ],
265
        'form_to_prop_functions' => ['trim'],
266
      ],
267

    
268
      'name' => [
269
        'property_name' => 'name',
270
        'schema' => [
271
          'type' => 'varchar',
272
          'length' => '60',
273
          'not null' => TRUE,
274
        ],
275
        'form' => [
276
          'field_group' => 'basic',
277
          '#type' => 'textfield',
278
          '#title' => t('Name'),
279
          '#description' => t('Choose a name for this query configuration.'),
280
          '#size' => 50,
281
          '#maxlength' => 255,
282
          '#required' => TRUE,
283
        ],
284
        'form_to_prop_functions' => ['trim'],
285
      ],
286

    
287
      'sid' => [
288
        'property_name' => 'sid',
289
        'schema' => [
290
          'type' => 'varchar',
291
          'length' => 20,
292
          'not null' => TRUE,
293
        ],
294
        'form' => [
295
          'field_group' => 'basic',
296
          '#type' => 'radios',
297
          '#title' => t('LDAP Server used for query.'),
298
          '#required' => 1,
299
        ],
300
        'form_to_prop_functions' => ['trim'],
301
      ],
302

    
303
      'status' => [
304
        'property_name' => 'status',
305
        'schema' => [
306
          'type' => 'int',
307
          'size' => 'tiny',
308
          'not null' => TRUE,
309
          'default' => 0,
310
        ],
311
        'form' => [
312
          'field_group' => 'basic',
313
          '#type' => 'checkbox',
314
          '#title' => t('Enabled'),
315
          '#description' => t('Disable in order to keep configuration without having it active.'),
316
        ],
317
        'form_to_prop_functions' => ['trim'],
318
      ],
319

    
320
      'base_dn_str' => [
321
        'property_name' => 'base_dn_str',
322
        'schema' => [
323
          'type' => 'text',
324
          'not null' => FALSE,
325
        ],
326
        'form' => [
327
          'field_group' => 'query',
328
          '#type' => 'textarea',
329
          '#title' => t('Base DNs to search in query.'),
330
          '#description' => t('Each Base DN will be queried and results merged. e.g. <code>ou=groups,dc=hogwarts,dc=edu</code>') . t('Enter one per line in case if you need more than one.'),
331
          '#cols' => 50,
332
          '#rows' => 6,
333
          '#required' => TRUE,
334
        ],
335
        'form_to_prop_functions' => ['trim'],
336
      ],
337

    
338
      'baseDn' => [
339
        'property_name' => 'baseDn',
340
        'exportable' => FALSE,
341
      ],
342

    
343
      'filter' => [
344
        'property_name' => 'filter',
345
        'schema' => [
346
          'type' => 'text',
347
          'not null' => FALSE,
348
        ],
349
        'form' => [
350
          'field_group' => 'query',
351
          '#type' => 'textarea',
352
          '#title' => t('Filter'),
353
          '#description' => t('LDAP query filter such as <code>(objectClass=group)</code> or <code>(&(objectClass=user)(homePhone=*))
354
</code>'),
355
          '#cols' => 50,
356
          '#rows' => 1,
357
          '#required' => TRUE,
358
        ],
359
        'form_to_prop_functions' => ['trim'],
360
      ],
361

    
362
      'attributes_str' => [
363
        'property_name' => 'attributes_str',
364
        'schema' => [
365
          'type' => 'text',
366
          'not null' => FALSE,
367
        ],
368
        'form' => [
369
          'field_group' => 'query',
370
          '#type' => 'textarea',
371
          '#title' => t('Attributes to return.'),
372
          '#description' => t('Enter as comma separated list. DN is automatically returned. Leave empty to return all attributes. e.g. <code>objectclass,name,cn,samaccountname</code>'),
373
          '#cols' => 50,
374
          '#rows' => 6,
375
        ],
376
        'form_to_prop_functions' => ['trim'],
377
      ],
378

    
379
      'attributes' => [
380
        'property_name' => 'attributes',
381
        'exportable' => FALSE,
382
      ],
383

    
384
      'sizelimit' => [
385
        'property_name' => 'sizelimit',
386
        'schema' => [
387
          'type' => 'int',
388
          'size' => 'small',
389
          'not null' => TRUE,
390
          'default' => 0,
391
        ],
392
        'form' => [
393
          'field_group' => 'query_advanced',
394
          '#type' => 'textfield',
395
          '#title' => t('Size Limit of returned data'),
396
          '#description' => t('This limit may be already set by the ldap server.  0 signifies no limit'),
397
          '#size' => 7,
398
          '#maxlength' => 5,
399
          '#required' => TRUE,
400
        ],
401
        'form_to_prop_functions' => ['trim'],
402
      ],
403

    
404
      'timelimit' => [
405
        'property_name' => 'timelimit',
406
        'schema' => [
407
          'type' => 'int',
408
          'size' => 'small',
409
          'not null' => TRUE,
410
          'default' => 0,
411

    
412
        ],
413
        'form' => [
414
          'field_group' => 'query_advanced',
415
          '#type' => 'textfield',
416
          '#title' => t('Time Limit in Seconds'),
417
          '#description' => t('The time limitset on this query.  This may be already set by the ldap server.  0 signifies no limit'),
418
          '#size' => 7,
419
          '#maxlength' => 5,
420
          '#required' => TRUE,
421
        ],
422
        'form_to_prop_functions' => ['trim'],
423
      ],
424

    
425
      'deref' => [
426
        'property_name' => 'deref',
427
        'schema' => [
428
          'type' => 'int',
429
          'size' => 'tiny',
430
          'not null' => TRUE,
431
          'default' => LDAP_DEREF_NEVER,
432
        ],
433
        'form' => [
434
          'field_group' => 'query_advanced',
435
          '#type' => 'radios',
436
          '#title' => t('How aliases should be handled during the search.'),
437
          '#required' => 1,
438
          '#options' => [
439
            LDAP_DEREF_NEVER => t('(default) aliases are never dereferenced.'),
440
            LDAP_DEREF_SEARCHING => t('aliases should be dereferenced during the search but not when locating the base object of the search.'),
441
            LDAP_DEREF_FINDING => t('aliases should be dereferenced when locating the base object but not during the search.'),
442
            LDAP_DEREF_ALWAYS => t('aliases should be dereferenced always.'),
443
          ],
444
        ],
445
        'form_to_prop_functions' => ['trim'],
446
      ],
447
      'scope' => [
448
        'property_name' => 'scope',
449
        'schema' => [
450
          'type' => 'int',
451
          'size' => 'tiny',
452
          'not null' => TRUE,
453
          'default' => LDAP_SCOPE_SUBTREE,
454
        ],
455
        'form' => [
456
          'field_group' => 'query_advanced',
457
          '#type' => 'radios',
458
          '#title' => t('Scope of search.'),
459
          '#required' => 1,
460
          '#options' => [
461
            LDAP_SCOPE_BASE => t('BASE. This value is used to indicate searching only the entry at the base DN, resulting in only that entry being returned (keeping in mind that it also has to meet the search filter criteria!).'),
462
            LDAP_SCOPE_ONELEVEL => t('ONELEVEL. This value is used to indicate searching all entries one level under the base DN - but not including the base DN and not including any entries under that one level under the base DN.'),
463
            LDAP_SCOPE_SUBTREE => t('SUBTREE. (default) This value is used to indicate searching of all entries at all levels under and including the specified base DN.'),
464
          ],
465
        ],
466
        'form_to_prop_functions' => ['trim'],
467
      ],
468

    
469
    ];
470
    return $fields;
471
  }
472

    
473
}