~ubuntu-branches/ubuntu/gutsy/samba/gutsy-updates

« back to all changes in this revision

Viewing changes to source/sam/idmap_ldap.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2006-11-28 20:14:37 UTC
  • mfrom: (0.10.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061128201437-a6x4lzlhempazocp
Tags: 3.0.23d-1ubuntu1
* Merge from debian unstable.
* Drop python2.4-samba, replace with python-samba. Added Conflicts/Replaces
  on python2.4-samba
* Drop track-connection-dos.patch, ubuntu-winbind-panic.patch, 
  ubuntu-fix-ldap.patch, ubuntu-setlocale.patch, ubuntu-setlocale-fixes.patch
* Remaining Ubuntu changes:
  - Revert Debian's installation of mount.cifs and umount.cifs as suid
  - Comment out the default [homes] shares and add more verbose comments to
    explain what they do and how they work (closes: launchpad.net/27608)
  - Add a "valid users = %S" stanza to the commented-out [homes] section, to
    show users how to restrict access to \\server\username to only username.
  - Change the (commented-out) "printer admin" example to use "@lpadmin"
    instead of "@ntadmin", since the lpadmin group is used for spool admin.
  - Alter the panic-action script to encourage users to report their
    bugs in Ubuntu packages to Ubuntu, rather than reporting to Debian.
    Modify text to more closely match the Debian script
  - Munge our init script to deal with the fact that our implementation
    (or lack thereof) of log_daemon_msg and log_progress_msg differs
    from Debian's implementation of the same (Ubuntu #19691)
  - Kept ubuntu-auxsrc.patch: some auxilliary sources (undocumented in 
    previous changelogs)
  - Set default workgroup to MSHOME

Show diffs side-by-side

added added

removed removed

Lines of Context:
113
113
        return NT_STATUS_OK;
114
114
}
115
115
 
116
 
/**********************************************************************
117
 
 Even if the sambaDomain attribute in LDAP tells us that this RID is 
118
 
 safe to use, always check before use.  
119
 
*********************************************************************/
120
 
 
121
 
static BOOL sid_in_use(struct ldap_idmap_state *state, 
122
 
                       const DOM_SID *sid, int *error) 
123
 
{
124
 
        fstring filter;
125
 
        fstring sid_string;
126
 
        LDAPMessage *result = NULL;
127
 
        int rc;
128
 
        const char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
129
 
 
130
 
        slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
131
 
 
132
 
        rc = smbldap_search_suffix(state->smbldap_state, 
133
 
                                   filter, sid_attr, &result);
134
 
 
135
 
        if (rc != LDAP_SUCCESS) {
136
 
                char *ld_error = NULL;
137
 
                ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
138
 
                DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
139
 
                          sid_string, ld_error));
140
 
                SAFE_FREE(ld_error);
141
 
 
142
 
                *error = rc;
143
 
                return True;
144
 
        }
145
 
        
146
 
        if ((ldap_count_entries(state->smbldap_state->ldap_struct, result)) > 0) {
147
 
                DEBUG(3, ("Sid %s already in use - trying next RID\n",
148
 
                          sid_string));
149
 
                ldap_msgfree(result);
150
 
                return True;
151
 
        }
152
 
 
153
 
        ldap_msgfree(result);
154
 
 
155
 
        /* good, sid is not in use */
156
 
        return False;
157
 
}
158
 
 
159
 
/**********************************************************************
160
 
 Set the new nextRid attribute, and return one we can use.
161
 
 
162
 
 This also checks that this RID is actually free - in case the admin
163
 
 manually stole it :-).
164
 
*********************************************************************/
165
 
 
166
 
static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid, 
167
 
                              int rid_type)
168
 
{
169
 
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
170
 
        LDAPMessage *domain_result = NULL;
171
 
        LDAPMessage *entry  = NULL;
172
 
        char *dn;
173
 
        LDAPMod **mods = NULL;
174
 
        fstring old_rid_string;
175
 
        fstring next_rid_string;
176
 
        fstring algorithmic_rid_base_string;
177
 
        uint32 next_rid;
178
 
        uint32 alg_rid_base;
179
 
        int attempts = 0;
180
 
        char *ld_error = NULL;
181
 
 
182
 
        while (attempts < 10) {
183
 
                if (!NT_STATUS_IS_OK(ret = smbldap_search_domain_info(state->smbldap_state, 
184
 
                                &domain_result, get_global_sam_name(), True))) {
185
 
                        return ret;
186
 
                }
187
 
        
188
 
                entry = ldap_first_entry(state->smbldap_state->ldap_struct, domain_result);
189
 
                if (!entry) {
190
 
                        DEBUG(0, ("Could not get domain info entry\n"));
191
 
                        ldap_msgfree(domain_result);
192
 
                        return ret;
193
 
                }
194
 
 
195
 
                if ((dn = smbldap_get_dn(state->smbldap_state->ldap_struct, entry)) == NULL) {
196
 
                        DEBUG(0, ("Could not get domain info DN\n"));
197
 
                        ldap_msgfree(domain_result);
198
 
                        return ret;
199
 
                }
200
 
 
201
 
                /* yes, we keep 3 seperate counters, one for rids between 1000 (BASE_RID) and 
202
 
                   algorithmic_rid_base.  The other two are to avoid stomping on the
203
 
                   different sets of algorithmic RIDs */
204
 
                
205
 
                if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
206
 
                                         get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
207
 
                                         algorithmic_rid_base_string)) {
208
 
                        
209
 
                        alg_rid_base = (uint32)atol(algorithmic_rid_base_string);
210
 
                } else {
211
 
                        alg_rid_base = algorithmic_rid_base();
212
 
                        /* Try to make the modification atomically by enforcing the
213
 
                           old value in the delete mod. */
214
 
                        slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string)-1, "%d", alg_rid_base);
215
 
                        smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, 
216
 
                                         get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), 
217
 
                                         algorithmic_rid_base_string);
218
 
                }
219
 
 
220
 
                next_rid = 0;
221
 
 
222
 
                if (alg_rid_base > BASE_RID) {
223
 
                        /* we have a non-default 'algorithmic rid base', so we have 'low' rids that we 
224
 
                           can allocate to new users */
225
 
                        if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
226
 
                                                 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID),
227
 
                                                 old_rid_string)) {
228
 
                                *rid = (uint32)atol(old_rid_string);
229
 
                        } else {
230
 
                                *rid = BASE_RID;
231
 
                        }
232
 
 
233
 
                        next_rid = *rid+1;
234
 
                        if (next_rid >= alg_rid_base) {
235
 
                                ldap_msgfree(domain_result);
236
 
                                return NT_STATUS_UNSUCCESSFUL;
237
 
                        }
238
 
                        
239
 
                        slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
240
 
                                
241
 
                        /* Try to make the modification atomically by enforcing the
242
 
                           old value in the delete mod. */
243
 
                        smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, 
244
 
                                         get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_RID), 
245
 
                                         next_rid_string);
246
 
                }
247
 
 
248
 
                if (!next_rid) { /* not got one already */
249
 
                        switch (rid_type) {
250
 
                        case USER_RID_TYPE:
251
 
                                if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
252
 
                                                         get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
253
 
                                                         old_rid_string)) {
254
 
                                        *rid = (uint32)atol(old_rid_string);                                    
255
 
                                }
256
 
                                break;
257
 
                        case GROUP_RID_TYPE:
258
 
                                if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry, 
259
 
                                                         get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
260
 
                                                         old_rid_string)) {
261
 
                                        *rid = (uint32)atol(old_rid_string);
262
 
                                }
263
 
                                break;
264
 
                        }
265
 
                        
266
 
                        /* This is the core of the whole routine. If we had
267
 
                           scheme-style closures, there would be a *lot* less code
268
 
                           duplication... */
269
 
 
270
 
                        next_rid = *rid+RID_MULTIPLIER;
271
 
                        slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
272
 
                        
273
 
                        switch (rid_type) {
274
 
                        case USER_RID_TYPE:
275
 
                                /* Try to make the modification atomically by enforcing the
276
 
                                   old value in the delete mod. */
277
 
                                smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods, 
278
 
                                                 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), 
279
 
                                                 next_rid_string);
280
 
                                break;
281
 
                                
282
 
                        case GROUP_RID_TYPE:
283
 
                                /* Try to make the modification atomically by enforcing the
284
 
                                   old value in the delete mod. */
285
 
                                smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
286
 
                                                 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
287
 
                                                 next_rid_string);
288
 
                                break;
289
 
                        }
290
 
                }
291
 
 
292
 
                if ((smbldap_modify(state->smbldap_state, dn, mods)) == LDAP_SUCCESS) {
293
 
                        DOM_SID dom_sid;
294
 
                        DOM_SID sid;
295
 
                        pstring domain_sid_string;
296
 
                        int error = 0;
297
 
 
298
 
                        if (!smbldap_get_single_pstring(state->smbldap_state->ldap_struct, domain_result,
299
 
                                        get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
300
 
                                        domain_sid_string)) {
301
 
                                ldap_mods_free(mods, True);
302
 
                                SAFE_FREE(dn);
303
 
                                ldap_msgfree(domain_result);
304
 
                                return ret;
305
 
                        }
306
 
 
307
 
                        if (!string_to_sid(&dom_sid, domain_sid_string)) { 
308
 
                                ldap_mods_free(mods, True);
309
 
                                SAFE_FREE(dn);
310
 
                                ldap_msgfree(domain_result);
311
 
                                return ret;
312
 
                        }
313
 
 
314
 
                        ldap_mods_free(mods, True);
315
 
                        mods = NULL;
316
 
                        SAFE_FREE(dn);
317
 
                        ldap_msgfree(domain_result);
318
 
 
319
 
                        sid_copy(&sid, &dom_sid);
320
 
                        sid_append_rid(&sid, *rid);
321
 
 
322
 
                        /* check RID is not in use */
323
 
                        if (sid_in_use(state, &sid, &error)) {
324
 
                                if (error) {
325
 
                                        return ret;
326
 
                                }
327
 
                                continue;
328
 
                        }
329
 
 
330
 
                        return NT_STATUS_OK;
331
 
                }
332
 
 
333
 
                ld_error = NULL;
334
 
                ldap_get_option(state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
335
 
                DEBUG(2, ("Failed to modify rid: %s\n", ld_error ? ld_error : "(NULL"));
336
 
                SAFE_FREE(ld_error);
337
 
 
338
 
                ldap_mods_free(mods, True);
339
 
                mods = NULL;
340
 
 
341
 
                SAFE_FREE(dn);
342
 
 
343
 
                ldap_msgfree(domain_result);
344
 
                domain_result = NULL;
345
 
 
346
 
                {
347
 
                        /* Sleep for a random timeout */
348
 
                        unsigned sleeptime = (sys_random()*sys_getpid()*attempts);
349
 
                        attempts += 1;
350
 
                        
351
 
                        sleeptime %= 100;
352
 
                        smb_msleep(sleeptime);
353
 
                }
354
 
        }
355
 
 
356
 
        DEBUG(0, ("Failed to set new RID\n"));
357
 
        return ret;
358
 
}
359
 
 
360
 
 
361
 
/*****************************************************************************
362
 
 Allocate a new RID
363
 
*****************************************************************************/
364
 
 
365
 
static NTSTATUS ldap_allocate_rid(uint32 *rid, int rid_type)
366
 
{
367
 
        return ldap_next_rid( &ldap_state, rid, rid_type );
368
 
}
369
 
 
370
116
/*****************************************************************************
371
117
 Allocate a new uid or gid
372
118
*****************************************************************************/
394
140
 
395
141
        pstr_sprintf(filter, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
396
142
 
397
 
        attr_list = get_attr_list( idpool_attr_list );
 
143
        attr_list = get_attr_list( NULL, idpool_attr_list );
398
144
 
399
145
        rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(),
400
146
                               LDAP_SCOPE_SUBTREE, filter,
401
147
                               attr_list, 0, &result);
402
 
        free_attr_list( attr_list );
 
148
        TALLOC_FREE( attr_list );
403
149
         
404
150
        if (rc != LDAP_SUCCESS) {
405
151
                DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL));
505
251
                LDAP_OBJ_IDMAP_ENTRY, type,  
506
252
                ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid));
507
253
                
508
 
        attr_list = get_attr_list( sidmap_attr_list );
 
254
        attr_list = get_attr_list( NULL, sidmap_attr_list );
509
255
        rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, 
510
256
                filter, attr_list, 0, &result);
511
257
 
534
280
 
535
281
        ret = NT_STATUS_OK;
536
282
out:
537
 
        free_attr_list( attr_list );     
 
283
        TALLOC_FREE( attr_list );        
538
284
 
539
285
        if (result)
540
286
                ldap_msgfree(result);
577
323
 
578
324
        /* do the search and check for errors */
579
325
 
580
 
        attr_list = get_attr_list( sidmap_attr_list );
 
326
        attr_list = get_attr_list( NULL, sidmap_attr_list );
581
327
        rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE, 
582
328
                filter, attr_list, 0, &result);
583
329
                        
651
397
        }
652
398
        
653
399
out:
654
 
        free_attr_list( attr_list );
 
400
        TALLOC_FREE( attr_list );
655
401
        if (result)
656
402
                ldap_msgfree(result);
657
403
        SAFE_FREE(dn);
674
420
        
675
421
        fstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_IDPOOL );
676
422
        
677
 
        attr_list = get_attr_list( idpool_attr_list );
 
423
        attr_list = get_attr_list( NULL, idpool_attr_list );
678
424
        rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), 
679
425
                LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result);
680
 
        free_attr_list ( attr_list );
 
426
        TALLOC_FREE( attr_list );
681
427
 
682
428
        if (rc != LDAP_SUCCESS)
683
429
                return NT_STATUS_UNSUCCESSFUL;
776
522
 
777
523
static struct idmap_methods ldap_methods = {
778
524
        ldap_idmap_init,
779
 
        ldap_allocate_rid,
780
525
        ldap_allocate_id,
781
526
        ldap_get_sid_from_id,
782
527
        ldap_get_id_from_sid,