r12608: Remove some unused #include lines.
[abartlet/samba.git/.git] / source4 / dsdb / samdb / ldb_modules / samba3sam.c
index 4680e17d0fbdf97ca42841cb114a47325f61b16f..f2c4441f9762bfc88c3c388b43333f68c368736d 100644 (file)
@@ -8,8 +8,9 @@
 #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[] = 
@@ -94,88 +277,123 @@ 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 */
@@ -187,8 +405,13 @@ const struct ldb_map_attribute samba3_attributes[] =
        /* 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 */
@@ -304,15 +527,25 @@ const struct ldb_map_attribute samba3_attributes[] =
        /* 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 */
@@ -603,6 +836,55 @@ const struct ldb_map_attribute samba3_attributes[] =
                .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,
        }