📄 ldap.c
字号:
} if (!ads_pull_sd(ads, ctx, msg, attrs[0], &psd)) { ret = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); goto ads_set_sd_error; } status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); if (!NT_STATUS_IS_OK(status)) { ret = ADS_ERROR_NT(status); goto ads_set_sd_error; } if (!prs_init(&ps_wire, sd_size, ctx, MARSHALL)) { ret = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; }#if 0 file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size);#endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); bval.bv_len = prs_offset(&ps_wire); bval.bv_val = TALLOC(ctx, bval.bv_len); if (!bval.bv_val) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } prs_set_offset(&ps_wire, 0); if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } ret = ads_mod_ber(ctx, &mods, attrs[0], &bval); if (ADS_ERR_OK(ret)) { ret = ads_gen_mod(ads, dn, mods); }ads_set_sd_error: ads_msgfree(ads, res); prs_mem_free(&ps_wire); talloc_destroy(ctx); return ret;}/** * pull the first entry from a ADS result * @param ads connection to ads server * @param res Results of search * @return first entry from result **/void *ads_first_entry(ADS_STRUCT *ads, void *res){ return (void *)ldap_first_entry(ads->ld, (LDAPMessage *)res);}/** * pull the next entry from a ADS result * @param ads connection to ads server * @param res Results of search * @return next entry from result **/void *ads_next_entry(ADS_STRUCT *ads, void *res){ return (void *)ldap_next_entry(ads->ld, (LDAPMessage *)res);}/** * pull a single string from a ADS result * @param ads connection to ads server * @param mem_ctx TALLOC_CTX to use for allocating result string * @param msg Results of search * @param field Attribute to retrieve * @return Result string in talloc context **/char *ads_pull_string(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field){ char **values; char *ret = NULL; char *ux_string; size_t rc; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); if (rc != (size_t)-1) ret = ux_string; } ldap_value_free(values); return ret;}/** * pull an array of strings from a ADS result * @param ads connection to ads server * @param mem_ctx TALLOC_CTX to use for allocating result string * @param msg Results of search * @param field Attribute to retrieve * @return Result strings in talloc context **/char **ads_pull_strings(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field, size_t *num_values){ char **values; char **ret = NULL; int i; values = ldap_get_values(ads->ld, msg, field); if (!values) return NULL; *num_values = ldap_count_values(values); ret = TALLOC_ARRAY(mem_ctx, char *, *num_values + 1); if (!ret) { ldap_value_free(values); return NULL; } for (i=0;i<*num_values;i++) { if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) { ldap_value_free(values); return NULL; } } ret[i] = NULL; ldap_value_free(values); return ret;}/** * pull an array of strings from a ADS result * (handle large multivalue attributes with range retrieval) * @param ads connection to ads server * @param mem_ctx TALLOC_CTX to use for allocating result string * @param msg Results of search * @param field Attribute to retrieve * @param current_strings strings returned by a previous call to this function * @param next_attribute The next query should ask for this attribute * @param num_values How many values did we get this time? * @param more_values Are there more values to get? * @return Result strings in talloc context **/char **ads_pull_strings_range(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field, char **current_strings, const char **next_attribute, size_t *num_strings, BOOL *more_strings){ char *attr; char *expected_range_attrib, *range_attr; BerElement *ptr = NULL; char **strings; char **new_strings; size_t num_new_strings; unsigned long int range_start; unsigned long int range_end; /* we might have been given the whole lot anyway */ if ((strings = ads_pull_strings(ads, mem_ctx, msg, field, num_strings))) { *more_strings = False; return strings; } expected_range_attrib = talloc_asprintf(mem_ctx, "%s;Range=", field); /* look for Range result */ for (attr = ldap_first_attribute(ads->ld, (LDAPMessage *)msg, &ptr); attr; attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr)) { /* we ignore the fact that this is utf8, as all attributes are ascii... */ if (strnequal(attr, expected_range_attrib, strlen(expected_range_attrib))) { range_attr = attr; break; } ldap_memfree(attr); } if (!attr) { ber_free(ptr, 0); /* nothing here - this field is just empty */ *more_strings = False; return NULL; } if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-%lu", &range_start, &range_end) == 2) { *more_strings = True; } else { if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-*", &range_start) == 1) { *more_strings = False; } else { DEBUG(1, ("ads_pull_strings_range: Cannot parse Range attriubte (%s)\n", range_attr)); ldap_memfree(range_attr); *more_strings = False; return NULL; } } if ((*num_strings) != range_start) { DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu" " - aborting range retreival\n", range_attr, (unsigned int)(*num_strings) + 1, range_start)); ldap_memfree(range_attr); *more_strings = False; return NULL; } new_strings = ads_pull_strings(ads, mem_ctx, msg, range_attr, &num_new_strings); if (*more_strings && ((*num_strings + num_new_strings) != (range_end + 1))) { DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu " "strings in this bunch, but we only got %lu - aborting range retreival\n", range_attr, (unsigned long int)range_end - range_start + 1, (unsigned long int)num_new_strings)); ldap_memfree(range_attr); *more_strings = False; return NULL; } strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *, *num_strings + num_new_strings); if (strings == NULL) { ldap_memfree(range_attr); *more_strings = False; return NULL; } memcpy(&strings[*num_strings], new_strings, sizeof(*new_strings) * num_new_strings); (*num_strings) += num_new_strings; if (*more_strings) { *next_attribute = talloc_asprintf(mem_ctx, "%s;range=%d-*", field, (int)*num_strings); if (!*next_attribute) { DEBUG(1, ("talloc_asprintf for next attribute failed!\n")); ldap_memfree(range_attr); *more_strings = False; return NULL; } } ldap_memfree(range_attr); return strings;}/** * pull a single uint32 from a ADS result * @param ads connection to ads server * @param msg Results of search * @param field Attribute to retrieve * @param v Pointer to int to store result * @return boolean inidicating success*/BOOL ads_pull_uint32(ADS_STRUCT *ads, void *msg, const char *field, uint32 *v){ char **values; values = ldap_get_values(ads->ld, msg, field); if (!values) return False; if (!values[0]) { ldap_value_free(values); return False; } *v = atoi(values[0]); ldap_value_free(values); return True;}/** * pull a single objectGUID from an ADS result * @param ads connection to ADS server * @param msg results of search * @param guid 37-byte area to receive text guid * @return boolean indicating success **/BOOL ads_pull_guid(ADS_STRUCT *ads, void *msg, struct uuid *guid){ char **values; UUID_FLAT flat_guid; values = ldap_get_values(ads->ld, msg, "objectGUID"); if (!values) return False; if (values[0]) { memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT)); smb_uuid_unpack(flat_guid, guid); ldap_value_free(values); return True; } ldap_value_free(values); return False;}/** * pull a single DOM_SID from a ADS result * @param ads connection to ads server * @param msg Results of search * @param field Attribute to retrieve * @param sid Pointer to sid to store result * @return boolean inidicating success*/BOOL ads_pull_sid(ADS_STRUCT *ads, void *msg, const char *field, DOM_SID *sid){ struct berval **values; BOOL ret = False; values = ldap_get_values_len(ads->ld, msg, field); if (!values) return False; if (values[0]) ret = sid_parse(values[0]->bv_val, values[0]->bv_len, sid); ldap_value_free_len(values); return ret;}/** * pull an array of DOM_SIDs from a ADS result * @param ads connection to ads server * @param mem_ctx TALLOC_CTX for allocating sid array * @param msg Results of search * @param field Attribute to retrieve * @param sids pointer to sid array to allocate * @return the count of SIDs pulled **/int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field, DOM_SID **sids){ struct berval **values; BOOL ret; int count, i; values = ldap_get_values_len(ads->ld, msg, field); if (!values) return 0; for (i=0; values[i]; i++) /* nop */ ; (*sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, i); if (!(*sids)) { ldap_value_free_len(values); return 0; } count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); if (ret) { fstring sid; DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count]))); count++; } } ldap_value_free_len(values); return count;}/** * pull a SEC_DESC from a ADS result * @param ads connection to ads server * @param mem_ctx TALLOC_CTX for allocating sid array * @param msg Results of search * @param field Attribute to retrieve * @param sd Pointer to *SEC_DESC to store result (talloc()ed) * @return boolean inidicating success*/BOOL ads_pull_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg, const char *field, SEC_DESC **sd){ struct berval **values; prs_struct ps; BOOL ret = False; values = ldap_get_values_len(ads->ld, msg, field); if (!values) return False; if (values[0]) { prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL); prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len); prs_set_offset(&ps,0); ret = sec_io_desc("sd", sd, &ps, 1); } ldap_value_free_len(values); return ret;}/* * in order to support usernames longer than 21 characters we need to * use both the sAMAccountName and the userPrincipalName attributes * It seems that not all users have the userPrincipalName attribute set * * @param ads connection to ads server * @param mem_ctx TALLOC_CTX for allocating sid array * @param msg Results of search * @return the username */char *ads_pull_username(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, void *msg){#if 0 /* JERRY */ char *ret, *p; /* lookup_name() only works on the sAMAccountName to returning the username portion of userPrincipalName breaks winbindd_getpwnam() */ ret = ads_pull_string(ads, mem_ctx, msg, "userPrincipalName"); if (ret && (p = strchr_m(ret, '@'))) { *p = 0; return ret; }#endif return ads_pull_string(ads, mem_ctx, msg, "sAMAccountName");}/** * find the update serial number - this is the core of the ldap cache * @param ads connection to ads server * @param ads connection to ADS server * @param usn Pointer to retrieved update serial number * @return status of search **/ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn){ const char *attrs[] = {"highestCommittedUSN", NULL}; ADS_STATUS status; void *res; status = ads_do_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res); if (!ADS_ERR_OK(status)) return status; if (ads_count_replies(ads, res)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -