113
113
return NT_STATUS_OK;
116
/**********************************************************************
117
Even if the sambaDomain attribute in LDAP tells us that this RID is
118
safe to use, always check before use.
119
*********************************************************************/
121
static BOOL sid_in_use(struct ldap_idmap_state *state,
122
const DOM_SID *sid, int *error)
126
LDAPMessage *result = NULL;
128
const char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
130
slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
132
rc = smbldap_search_suffix(state->smbldap_state,
133
filter, sid_attr, &result);
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));
146
if ((ldap_count_entries(state->smbldap_state->ldap_struct, result)) > 0) {
147
DEBUG(3, ("Sid %s already in use - trying next RID\n",
149
ldap_msgfree(result);
153
ldap_msgfree(result);
155
/* good, sid is not in use */
159
/**********************************************************************
160
Set the new nextRid attribute, and return one we can use.
162
This also checks that this RID is actually free - in case the admin
163
manually stole it :-).
164
*********************************************************************/
166
static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
169
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
170
LDAPMessage *domain_result = NULL;
171
LDAPMessage *entry = NULL;
173
LDAPMod **mods = NULL;
174
fstring old_rid_string;
175
fstring next_rid_string;
176
fstring algorithmic_rid_base_string;
180
char *ld_error = NULL;
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))) {
188
entry = ldap_first_entry(state->smbldap_state->ldap_struct, domain_result);
190
DEBUG(0, ("Could not get domain info entry\n"));
191
ldap_msgfree(domain_result);
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);
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 */
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)) {
209
alg_rid_base = (uint32)atol(algorithmic_rid_base_string);
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);
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),
228
*rid = (uint32)atol(old_rid_string);
234
if (next_rid >= alg_rid_base) {
235
ldap_msgfree(domain_result);
236
return NT_STATUS_UNSUCCESSFUL;
239
slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
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),
248
if (!next_rid) { /* not got one already */
251
if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
252
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
254
*rid = (uint32)atol(old_rid_string);
258
if (smbldap_get_single_pstring(state->smbldap_state->ldap_struct, entry,
259
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
261
*rid = (uint32)atol(old_rid_string);
266
/* This is the core of the whole routine. If we had
267
scheme-style closures, there would be a *lot* less code
270
next_rid = *rid+RID_MULTIPLIER;
271
slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
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),
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),
292
if ((smbldap_modify(state->smbldap_state, dn, mods)) == LDAP_SUCCESS) {
295
pstring domain_sid_string;
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);
303
ldap_msgfree(domain_result);
307
if (!string_to_sid(&dom_sid, domain_sid_string)) {
308
ldap_mods_free(mods, True);
310
ldap_msgfree(domain_result);
314
ldap_mods_free(mods, True);
317
ldap_msgfree(domain_result);
319
sid_copy(&sid, &dom_sid);
320
sid_append_rid(&sid, *rid);
322
/* check RID is not in use */
323
if (sid_in_use(state, &sid, &error)) {
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"));
338
ldap_mods_free(mods, True);
343
ldap_msgfree(domain_result);
344
domain_result = NULL;
347
/* Sleep for a random timeout */
348
unsigned sleeptime = (sys_random()*sys_getpid()*attempts);
352
smb_msleep(sleeptime);
356
DEBUG(0, ("Failed to set new RID\n"));
361
/*****************************************************************************
363
*****************************************************************************/
365
static NTSTATUS ldap_allocate_rid(uint32 *rid, int rid_type)
367
return ldap_next_rid( &ldap_state, rid, rid_type );
370
116
/*****************************************************************************
371
117
Allocate a new uid or gid
372
118
*****************************************************************************/