📄 util.c
字号:
TALLOC_CTX *mem_ctx, struct ldb_dn *domain_dn, struct ldb_message *msg){ uint64_t attr_time = samdb_result_uint64(msg, "pwdLastSet", 0); uint32_t userAccountControl = samdb_result_uint64(msg, "userAccountControl", 0); int64_t maxPwdAge; /* Machine accounts don't expire, and there is a flag for 'no expiry' */ if (!(userAccountControl & UF_NORMAL_ACCOUNT) || (userAccountControl & UF_DONT_EXPIRE_PASSWD)) { return 0x7FFFFFFFFFFFFFFFULL; } if (attr_time == 0) { return 0; } maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn, "maxPwdAge", NULL); if (maxPwdAge == 0) { return 0x7FFFFFFFFFFFFFFFULL; } else { attr_time -= maxPwdAge; } return attr_time;}/* pull a samr_Password structutre from a result set. */struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr){ struct samr_Password *hash = NULL; const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr); if (val && (val->length >= sizeof(hash->hash))) { hash = talloc(mem_ctx, struct samr_Password); memcpy(hash->hash, val->data, MIN(val->length, sizeof(hash->hash))); } return hash;}/* pull an array of samr_Password structutres from a result set. */uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr, struct samr_Password **hashes){ uint_t count = 0; const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr); int i; *hashes = NULL; if (!val) { return 0; } count = val->length / 16; if (count == 0) { return 0; } *hashes = talloc_array(mem_ctx, struct samr_Password, count); if (! *hashes) { return 0; } for (i=0;i<count;i++) { memcpy((*hashes)[i].hash, (i*16)+(char *)val->data, 16); } return count;}NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct samr_Password **lm_pwd, struct samr_Password **nt_pwd) { struct samr_Password *lmPwdHash, *ntPwdHash; if (nt_pwd) { int num_nt; num_nt = samdb_result_hashes(mem_ctx, msg, "unicodePwd", &ntPwdHash); if (num_nt == 0) { *nt_pwd = NULL; } else if (num_nt > 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { *nt_pwd = &ntPwdHash[0]; } } if (lm_pwd) { int num_lm; num_lm = samdb_result_hashes(mem_ctx, msg, "dBCSPwd", &lmPwdHash); if (num_lm == 0) { *lm_pwd = NULL; } else if (num_lm > 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } else { *lm_pwd = &lmPwdHash[0]; } } return NT_STATUS_OK;}/* pull a samr_LogonHours structutre from a result set. */struct samr_LogonHours samdb_result_logon_hours(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr){ struct samr_LogonHours hours; const int units_per_week = 168; const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr); ZERO_STRUCT(hours); hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week); if (!hours.bits) { return hours; } hours.units_per_week = units_per_week; memset(hours.bits, 0xFF, units_per_week); if (val) { memcpy(hours.bits, val->data, MIN(val->length, units_per_week)); } return hours;}/* pull a set of account_flags from a result set. This requires that the attributes: pwdLastSet userAccountControl be included in 'msg'*/uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct ldb_dn *domain_dn){ uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0); uint32_t acct_flags = samdb_uf2acb(userAccountControl); NTTIME must_change_time; NTTIME now; must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, domain_dn, msg); /* Test account expire time */ unix_to_nt_time(&now, time(NULL)); /* check for expired password */ if (must_change_time < now) { acct_flags |= ACB_PW_EXPIRED; } return acct_flags;}/* Find an attribute, with a particular value *//* The current callers of this function expect a very specific * behaviour: In particular, objectClass subclass equivilance is not * wanted. This means that we should not lookup the schema for the * comparison function */struct ldb_message_element *samdb_find_attribute(struct ldb_context *ldb, const struct ldb_message *msg, const char *name, const char *value){ int i; struct ldb_message_element *el = ldb_msg_find_element(msg, name); if (!el) { return NULL; } for (i=0;i<el->num_values;i++) { if (ldb_attr_cmp(value, (char *)el->values[i].data) == 0) { return el; } } return NULL;}int samdb_find_or_add_value(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value){ if (samdb_find_attribute(ldb, msg, name, set_value) == NULL) { return samdb_msg_add_string(ldb, msg, msg, name, set_value); } return LDB_SUCCESS;}int samdb_find_or_add_attribute(struct ldb_context *ldb, struct ldb_message *msg, const char *name, const char *set_value){ struct ldb_message_element *el; el = ldb_msg_find_element(msg, name); if (el) { return LDB_SUCCESS; } return samdb_msg_add_string(ldb, msg, msg, name, set_value);}/* add a string element to a message*/int samdb_msg_add_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, const char *str){ char *s = talloc_strdup(mem_ctx, str); char *a = talloc_strdup(mem_ctx, attr_name); if (s == NULL || a == NULL) { return LDB_ERR_OPERATIONS_ERROR; } return ldb_msg_add_string(msg, a, s);}/* add a dom_sid element to a message*/int samdb_msg_add_dom_sid(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, struct dom_sid *sid){ struct ldb_val v; enum ndr_err_code ndr_err; ndr_err = ndr_push_struct_blob(&v, mem_ctx, lp_iconv_convenience(ldb_get_opaque(sam_ldb, "loadparm")), sid, (ndr_push_flags_fn_t)ndr_push_dom_sid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return -1; } return ldb_msg_add_value(msg, attr_name, &v, NULL);}/* add a delete element operation to a message*/int samdb_msg_add_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name){ /* we use an empty replace rather than a delete, as it allows for samdb_replace() to be used everywhere */ return ldb_msg_add_empty(msg, attr_name, LDB_FLAG_MOD_REPLACE, NULL);}/* add a add attribute value to a message*/int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, const char *value){ struct ldb_message_element *el; char *a, *v; int ret; a = talloc_strdup(mem_ctx, attr_name); if (a == NULL) return -1; v = talloc_strdup(mem_ctx, value); if (v == NULL) return -1; ret = ldb_msg_add_string(msg, a, v); if (ret != 0) return ret; el = ldb_msg_find_element(msg, a); if (el == NULL) return -1; el->flags = LDB_FLAG_MOD_ADD; return 0;}/* add a delete attribute value to a message*/int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, const char *value){ struct ldb_message_element *el; char *a, *v; int ret; a = talloc_strdup(mem_ctx, attr_name); if (a == NULL) return -1; v = talloc_strdup(mem_ctx, value); if (v == NULL) return -1; ret = ldb_msg_add_string(msg, a, v); if (ret != 0) return ret; el = ldb_msg_find_element(msg, a); if (el == NULL) return -1; el->flags = LDB_FLAG_MOD_DELETE; return 0;}/* add a int element to a message*/int samdb_msg_add_int(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, int v){ const char *s = talloc_asprintf(mem_ctx, "%d", v); return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, s);}/* add a uint_t element to a message*/int samdb_msg_add_uint(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, uint_t v){ const char *s = talloc_asprintf(mem_ctx, "%u", v); return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, s);}/* add a (signed) int64_t element to a message*/int samdb_msg_add_int64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, int64_t v){ const char *s = talloc_asprintf(mem_ctx, "%lld", (long long)v); return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, s);}/* add a uint64_t element to a message*/int samdb_msg_add_uint64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, uint64_t v){ const char *s = talloc_asprintf(mem_ctx, "%llu", (unsigned long long)v); return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, s);}/* add a samr_Password element to a message*/int samdb_msg_add_hash(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, struct samr_Password *hash){ struct ldb_val val; val.data = talloc_memdup(mem_ctx, hash->hash, 16); if (!val.data) { return -1; } val.length = 16; return ldb_msg_add_value(msg, attr_name, &val, NULL);}/* add a samr_Password array to a message*/int samdb_msg_add_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, struct samr_Password *hashes, uint_t count){ struct ldb_val val; int i; val.data = talloc_array_size(mem_ctx, 16, count); val.length = count*16; if (!val.data) { return -1; } for (i=0;i<count;i++) { memcpy(i*16 + (char *)val.data, hashes[i].hash, 16); } return ldb_msg_add_value(msg, attr_name, &val, NULL);}/* add a acct_flags element to a message*/int samdb_msg_add_acct_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, uint32_t v){ return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, samdb_acb2uf(v));}/* add a logon_hours element to a message*/int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, struct samr_LogonHours *hours){ struct ldb_val val; val.length = hours->units_per_week / 8; val.data = hours->bits; return ldb_msg_add_value(msg, attr_name, &val, NULL);}/* add a general value element to a message*/int samdb_msg_add_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, const struct ldb_val *val){ return ldb_msg_add_value(msg, attr_name, val, NULL);}/* sets a general value element to a message*/int samdb_msg_set_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, const struct ldb_val *val){ struct ldb_message_element *el; el = ldb_msg_find_element(msg, attr_name); if (el) { el->num_values = 0; } return ldb_msg_add_value(msg, attr_name, val, NULL);}/* set a string element in a message*/int samdb_msg_set_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr_name, const char *str){ struct ldb_message_element *el; el = ldb_msg_find_element(msg, attr_name); if (el) { el->num_values = 0; } return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, str);}/* replace elements in a record*/int samdb_replace(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg){ int i; /* mark all the message elements as LDB_FLAG_MOD_REPLACE */ for (i=0;i<msg->num_elements;i++) { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } /* modify the samdb record */ return ldb_modify(sam_ldb, msg);}/* return a default security descriptor*/struct security_descriptor *samdb_default_security_descriptor(TALLOC_CTX *mem_ctx){ struct security_descriptor *sd; sd = security_descriptor_initialise(mem_ctx); return sd;}struct ldb_dn *samdb_base_dn(struct ldb_context *sam_ctx) { return ldb_get_default_basedn(sam_ctx);}struct ldb_dn *samdb_config_dn(struct ldb_context *sam_ctx) { return ldb_get_config_basedn(sam_ctx);}struct ldb_dn *samdb_schema_dn(struct ldb_context *sam_ctx) { return ldb_get_schema_basedn(sam_ctx);}struct ldb_dn *samdb_root_dn(struct ldb_context *sam_ctx) { return ldb_get_root_basedn(sam_ctx);}struct ldb_dn *samdb_partitions_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx){ struct ldb_dn *new_dn; new_dn = ldb_dn_copy(mem_ctx, samdb_config_dn(sam_ctx)); if ( ! ldb_dn_add_child_fmt(new_dn, "CN=Partitions")) { talloc_free(new_dn); return NULL; } return new_dn;}struct ldb_dn *samdb_sites_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx){ struct ldb_dn *new_dn; new_dn = ldb_dn_copy(mem_ctx, samdb_config_dn(sam_ctx)); if ( ! ldb_dn_add_child_fmt(new_dn, "CN=Sites")) { talloc_free(new_dn); return NULL; } return new_dn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -