#include "ldb/modules/ldb_map.h"
#include "ldb/include/ldb.h"
#include "ldb/include/ldb_private.h"
+#include "system/passwd.h"
-/* FIXME:
+/*
* sambaSID -> member (dn!)
* sambaSIDList -> member (dn!)
* sambaDomainName -> name
/* In Samba4 but not in Samba3:
*/
-static struct ldb_val convert_sid_rid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+static void generate_hashes (struct ldb_module *module, const char *local_attr, const struct ldb_message *local, struct ldb_message *remote_mp, struct ldb_message *remote_fb)
{
- printf("Converting SID TO RID *\n");
+ const char *upwd = ldb_msg_find_string(local, local_attr, NULL);
+ struct ldb_val val;
- /* FIXME */
+ if (!upwd)
+ return;
- return ldb_val_dup(ctx, val);
+ ldb_msg_add_string(remote_fb, local_attr, upwd);
+
+ val.length = 16;
+ val.data = talloc_zero_size(module, val.length);
+
+ E_md4hash(upwd, val.data);
+ ldb_msg_add_value(remote_mp, "sambaNTPassword", &val);
+
+ val.data = talloc_zero_size(module, val.length);
+ E_deshash(upwd, val.data);
+ ldb_msg_add_value(remote_mp, "sambaLMPassword", &val);
}
-static struct ldb_val convert_rid_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+
+static struct ldb_message_element *generate_primaryGroupID(struct ldb_module *module, TALLOC_CTX *ctx, const char *attr, const struct ldb_message *remote)
{
- printf("Converting RID TO SID *\n");
+ struct ldb_message_element *el;
+ const char *sid = ldb_msg_find_string(remote, attr, NULL);
- /* FIXME */
+ if (!sid)
+ return NULL;
- return ldb_val_dup(ctx, val);
+ if (strchr(sid, '-') == NULL)
+ return NULL;
+
+ el = talloc_zero(ctx, struct ldb_message_element);
+ el->name = talloc_strdup(ctx, "primaryGroupID");
+ el->num_values = 1;
+ el->values = talloc_array(ctx, struct ldb_val, 1);
+ el->values[0].data = (uint8_t *)talloc_strdup(ctx, strchr(sid, '-')+1);
+ el->values[0].length = strlen((char *)el->values[0].data);
+
+ return el;
}
-static struct ldb_val convert_unix_id2name(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+static void generate_sambaPrimaryGroupSID(struct ldb_module *module, const char *local_attr, const struct ldb_message *local, struct ldb_message *remote_mp, struct ldb_message *remote_fb)
{
- printf("Converting UNIX ID to name\n");
+ const struct ldb_val *sidval;
+ char *sidstring;
+ struct dom_sid *sid;
+ NTSTATUS status;
+
+ sidval = ldb_msg_find_ldb_val(local, "objectSid");
+
+ if (!sidval)
+ return; /* Sorry, no SID today.. */
+
+ sid = talloc(remote_mp, struct dom_sid);
+ if (sid == NULL) {
+ return;
+ }
+ status = ndr_pull_struct_blob(sidval, sid, sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(sid);
+ return;
+ }
+
+ if (!ldb_msg_find_ldb_val(local, "primaryGroupID"))
+ return; /* Sorry, no SID today.. */
+
+ sid->num_auths--;
- /* FIXME */
+ sidstring = dom_sid_string(remote_mp, sid);
+ talloc_free(sid);
+ ldb_msg_add_fmt(remote_mp, "sambaPrimaryGroupSID", "%s-%d", sidstring, ldb_msg_find_uint(local, "primaryGroupID", 0));
+ talloc_free(sidstring);
+}
+static struct ldb_val convert_uid_samaccount(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
return ldb_val_dup(ctx, val);
}
-static struct ldb_val convert_unix_name2id(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+static struct ldb_val lookup_homedir(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
{
- printf("Converting UNIX name to ID\n");
+ struct passwd *pwd;
+ struct ldb_val retval;
+
+ pwd = getpwnam((char *)val->data);
- /* FIXME */
+ if (!pwd) {
+ ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Unable to lookup '%s' in passwd", (char *)val->data);
+ return *talloc_zero(ctx, struct ldb_val);
+ }
- return ldb_val_dup(ctx, val);
+ retval.data = (uint8_t *)talloc_strdup(ctx, pwd->pw_dir);
+ retval.length = strlen((char *)retval.data);
+
+ return retval;
+}
+
+static struct ldb_val lookup_gid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ struct passwd *pwd;
+ struct ldb_val retval;
+
+ pwd = getpwnam((char *)val->data);
+
+ if (!pwd) {
+ return *talloc_zero(ctx, struct ldb_val);
+ }
+
+ retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_gid);
+ retval.length = strlen((char *)retval.data);
+
+ return retval;
+}
+
+static struct ldb_val lookup_uid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ struct passwd *pwd;
+ struct ldb_val retval;
+
+ pwd = getpwnam((char *)val->data);
+
+ if (!pwd) {
+ return *talloc_zero(ctx, struct ldb_val);
+ }
+
+ retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_uid);
+ retval.length = strlen((char *)retval.data);
+
+ return retval;
+}
+
+static struct ldb_val encode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ struct dom_sid *sid = dom_sid_parse_talloc(ctx, (char *)val->data);
+ struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
+ NTSTATUS status;
+
+ if (sid == NULL) {
+ return *out;
+ }
+ status = ndr_push_struct_blob(out, ctx, sid,
+ (ndr_push_flags_fn_t)ndr_push_dom_sid);
+ talloc_free(sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ return *out;
+ }
+
+ return *out;
+}
+
+static struct ldb_val decode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
+{
+ struct dom_sid *sid;
+ NTSTATUS status;
+ struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
+
+ sid = talloc(ctx, struct dom_sid);
+ if (sid == NULL) {
+ return *out;
+ }
+ status = ndr_pull_struct_blob(val, sid, sid,
+ (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(sid);
+ return *out;
+ }
+ out->data = (uint8_t *)dom_sid_string(ctx, sid);
+ talloc_free(sid);
+ if (out->data == NULL) {
+ return *out;
+ }
+ out->length = strlen((const char *)out->data);
+
+ return *out;
}
const struct ldb_map_objectclass samba3_objectclasses[] = {
- { "group", "sambaGroupMapping" },
- { "user", "sambaSAMAccount" },
- { "domain", "sambaDomain" },
- { NULL, NULL }
+ {
+ .local_name = "user",
+ .remote_name = "posixAccount",
+ .base_classes = { "top", NULL },
+ .musts = { "cn", "uid", "uidNumber", "gidNumber", "homeDirectory", NULL },
+ .mays = { "userPassword", "loginShell", "gecos", "description", NULL },
+ },
+ {
+ .local_name = "group",
+ .remote_name = "posixGroup",
+ .base_classes = { "top", NULL },
+ .musts = { "cn", "gidNumber", NULL },
+ .mays = { "userPassword", "memberUid", "description", NULL },
+ },
+ {
+ .local_name = "group",
+ .remote_name = "sambaGroupMapping",
+ .base_classes = { "top", "posixGroup", NULL },
+ .musts = { "gidNumber", "sambaSID", "sambaGroupType", NULL },
+ .mays = { "displayName", "description", "sambaSIDList", NULL },
+ },
+ {
+ .local_name = "user",
+ .remote_name = "sambaSAMAccount",
+ .base_classes = { "top", "posixAccount", NULL },
+ .musts = { "uid", "sambaSID", NULL },
+ .mays = { "cn", "sambaLMPassword", "sambaNTPassword",
+ "sambaPwdLastSet", "sambaLogonTime", "sambaLogoffTime",
+ "sambaKickoffTime", "sambaPwdCanChange", "sambaPwdMustChange",
+ "sambaAcctFlags", "displayName", "sambaHomePath", "sambaHomeDrive",
+ "sambaLogonScript", "sambaProfilePath", "description", "sambaUserWorkstations",
+ "sambaPrimaryGroupSID", "sambaDomainName", "sambaMungedDial",
+ "sambaBadPasswordCount", "sambaBadPasswordTime",
+ "sambaPasswordHistory", "sambaLogonHours", NULL }
+
+ },
+ {
+ .local_name = "domain",
+ .remote_name = "sambaDomain",
+ .base_classes = { "top", NULL },
+ .musts = { "sambaDomainName", "sambaSID", NULL },
+ .mays = { "sambaNextRid", "sambaNextGroupRid", "sambaNextUserRid", "sambaAlgorithmicRidBase", NULL },
+ },
+ { NULL, NULL }
};
const struct ldb_map_attribute samba3_attributes[] =
{
.local_name = "nextRid",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaNextRid",
+ .u = {
+ .rename = {
+ .remote_name = "sambaNextRid",
+ },
+ },
},
/* sambaBadPasswordTime -> badPasswordtime*/
{
.local_name = "badPasswordTime",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaBadPasswordTime",
+ .u = {
+ .rename = {
+ .remote_name = "sambaBadPasswordTime",
+ },
+ },
},
/* sambaLMPassword -> lmPwdHash*/
{
.local_name = "lmPwdHash",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaLMPassword",
+ .u = {
+ .rename = {
+ .remote_name = "sambaLMPassword",
+ },
+ },
},
/* sambaGroupType -> groupType */
{
.local_name = "groupType",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaGroupType",
+ .u = {
+ .rename = {
+ .remote_name = "sambaGroupType",
+ },
+ },
},
/* sambaNTPassword -> ntPwdHash*/
{
- .local_name = "badPwdCount",
+ .local_name = "ntPwdHash",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaNTPassword",
+ .u = {
+ .rename = {
+ .remote_name = "sambaNTPassword",
+ },
+ },
},
/* sambaPrimaryGroupSID -> primaryGroupID */
{
.local_name = "primaryGroupID",
- .type = MAP_CONVERT,
- .u.convert.remote_name = "sambaPrimaryGroupSID",
- .u.convert.convert_local = convert_rid_sid,
- .u.convert.convert_remote = convert_sid_rid,
+ .type = MAP_GENERATE,
+ .u = {
+ .generate = {
+ .remote_names = { "sambaPrimaryGroupSID", NULL },
+ .generate_local = generate_primaryGroupID,
+ .generate_remote = generate_sambaPrimaryGroupSID,
+ },
+ },
},
/* sambaBadPasswordCount -> badPwdCount */
{
.local_name = "badPwdCount",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaBadPasswordCount",
+ .u = {
+ .rename = {
+ .remote_name = "sambaBadPasswordCount",
+ },
+ },
},
/* sambaLogonTime -> lastLogon*/
{
.local_name = "lastLogon",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaLogonTime",
+ .u = {
+ .rename = {
+ .remote_name = "sambaLogonTime",
+ },
+ },
},
/* sambaLogoffTime -> lastLogoff*/
{
.local_name = "lastLogoff",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaLogoffTime",
- },
-
- /* gidNumber -> unixName */
- {
- .local_name = "unixName",
- .type = MAP_CONVERT,
- .u.convert.remote_name = "gidNumber",
- .u.convert.convert_local = convert_unix_name2id,
- .u.convert.convert_remote = convert_unix_id2name,
+ .u = {
+ .rename = {
+ .remote_name = "sambaLogoffTime",
+ },
+ },
},
/* uid -> unixName */
{
.local_name = "unixName",
.type = MAP_RENAME,
- .u.convert.remote_name = "uid",
+ .u = {
+ .rename = {
+ .remote_name = "uid",
+ },
+ },
},
/* displayName -> name */
{
.local_name = "name",
.type = MAP_RENAME,
- .u.rename.remote_name = "displayName",
+ .u = {
+ .rename = {
+ .remote_name = "displayName",
+ },
+ },
},
/* cn */
/* sAMAccountName -> cn */
{
.local_name = "sAMAccountName",
- .type = MAP_RENAME,
- .u.rename.remote_name = "uid",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "uid",
+ .convert_remote = convert_uid_samaccount,
+ },
+ },
},
/* objectCategory */
/* sambaSID -> objectSid*/
{
.local_name = "objectSid",
- .type = MAP_RENAME,
- .u.rename.remote_name = "sambaSID",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "sambaSID",
+ .convert_local = decode_sid,
+ .convert_remote = encode_sid,
+ },
+ },
},
/* sambaPwdLastSet -> pwdLastSet */
{
.local_name = "pwdLastSet",
.type = MAP_RENAME,
- .u.rename.remote_name = "sambaPwdLastSet",
+ .u = {
+ .rename = {
+ .remote_name = "sambaPwdLastSet",
+ },
+ },
},
/* accountExpires */
.type = MAP_IGNORE,
},
+ /* uidNumber */
+ {
+ .local_name = "unixName",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "uidNumber",
+ .convert_local = lookup_uid,
+ },
+ },
+ },
+
+ /* gidNumber. Perhaps make into generate so we can distinguish between
+ * groups and accounts? */
+ {
+ .local_name = "unixName",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "gidNumber",
+ .convert_local = lookup_gid,
+ },
+ },
+ },
+
+ /* homeDirectory */
+ {
+ .local_name = "unixName",
+ .type = MAP_CONVERT,
+ .u = {
+ .convert = {
+ .remote_name = "homeDirectory",
+ .convert_local = lookup_homedir,
+ },
+ },
+ },
+
+ /* unicodePwd */
+ {
+ .local_name = "unicodePwd",
+ .type = MAP_GENERATE,
+ .u = {
+ .generate = {
+ .remote_names = { "sambaNTPassword", "sambaLMPassword", NULL },
+ .generate_local = NULL,
+ .generate_remote = generate_hashes
+ },
+ },
+ },
{
.local_name = NULL,
}