2 ldb database library - Samba3 SAM compatibility backend
4 Copyright (C) Jelmer Vernooij 2005
8 #include "ldb/modules/ldb_map.h"
9 #include "ldb/include/ldb.h"
10 #include "ldb/include/ldb_private.h"
11 #include "system/passwd.h"
14 * sambaSID -> member (dn!)
15 * sambaSIDList -> member (dn!)
16 * sambaDomainName -> name
22 * sambaAcctFlags -> systemFlags ?
23 * sambaPasswordHistory -> ntPwdHistory*/
31 * sambaAlgorithmicRidBase
42 * sambaUserWorkstations
46 /* In Samba4 but not in Samba3:
49 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)
51 const char *upwd = ldb_msg_find_string(local, local_attr, NULL);
57 ldb_msg_add_string(remote_fb, local_attr, upwd);
60 val.data = talloc_zero_size(module, val.length);
62 E_md4hash(upwd, val.data);
63 ldb_msg_add_value(remote_mp, "sambaNTPassword", &val);
65 val.data = talloc_zero_size(module, val.length);
66 E_deshash(upwd, val.data);
67 ldb_msg_add_value(remote_mp, "sambaLMPassword", &val);
71 static struct ldb_message_element *generate_primaryGroupID(struct ldb_module *module, TALLOC_CTX *ctx, const char *attr, const struct ldb_message *remote)
73 struct ldb_message_element *el;
74 const char *sid = ldb_msg_find_string(remote, attr, NULL);
79 if (strchr(sid, '-') == NULL)
82 el = talloc_zero(ctx, struct ldb_message_element);
83 el->name = talloc_strdup(ctx, "primaryGroupID");
85 el->values = talloc_array(ctx, struct ldb_val, 1);
86 el->values[0].data = (uint8_t *)talloc_strdup(ctx, strchr(sid, '-')+1);
87 el->values[0].length = strlen((char *)el->values[0].data);
92 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)
94 const struct ldb_val *sidval;
99 sidval = ldb_msg_find_ldb_val(local, "objectSid");
102 return; /* Sorry, no SID today.. */
104 sid = talloc(remote_mp, struct dom_sid);
108 status = ndr_pull_struct_blob(sidval, sid, sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
109 if (!NT_STATUS_IS_OK(status)) {
114 if (!ldb_msg_find_ldb_val(local, "primaryGroupID"))
115 return; /* Sorry, no SID today.. */
119 sidstring = dom_sid_string(remote_mp, sid);
121 ldb_msg_add_fmt(remote_mp, "sambaPrimaryGroupSID", "%s-%d", sidstring, ldb_msg_find_uint(local, "primaryGroupID", 0));
122 talloc_free(sidstring);
125 static struct ldb_val convert_uid_samaccount(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
127 return ldb_val_dup(ctx, val);
130 static struct ldb_val lookup_homedir(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
133 struct ldb_val retval;
135 pwd = getpwnam((char *)val->data);
138 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Unable to lookup '%s' in passwd", (char *)val->data);
139 return *talloc_zero(ctx, struct ldb_val);
142 retval.data = (uint8_t *)talloc_strdup(ctx, pwd->pw_dir);
143 retval.length = strlen((char *)retval.data);
148 static struct ldb_val lookup_gid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
151 struct ldb_val retval;
153 pwd = getpwnam((char *)val->data);
156 return *talloc_zero(ctx, struct ldb_val);
159 retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_gid);
160 retval.length = strlen((char *)retval.data);
165 static struct ldb_val lookup_uid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
168 struct ldb_val retval;
170 pwd = getpwnam((char *)val->data);
173 return *talloc_zero(ctx, struct ldb_val);
176 retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_uid);
177 retval.length = strlen((char *)retval.data);
182 static struct ldb_val encode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
184 struct dom_sid *sid = dom_sid_parse_talloc(ctx, (char *)val->data);
185 struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
191 status = ndr_push_struct_blob(out, ctx, sid,
192 (ndr_push_flags_fn_t)ndr_push_dom_sid);
194 if (!NT_STATUS_IS_OK(status)) {
201 static struct ldb_val decode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
205 struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
207 sid = talloc(ctx, struct dom_sid);
211 status = ndr_pull_struct_blob(val, sid, sid,
212 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
213 if (!NT_STATUS_IS_OK(status)) {
217 out->data = (uint8_t *)dom_sid_string(ctx, sid);
219 if (out->data == NULL) {
222 out->length = strlen((const char *)out->data);
227 const struct ldb_map_objectclass samba3_objectclasses[] = {
229 .local_name = "user",
230 .remote_name = "posixAccount",
231 .base_classes = { "top", NULL },
232 .musts = { "cn", "uid", "uidNumber", "gidNumber", "homeDirectory", NULL },
233 .mays = { "userPassword", "loginShell", "gecos", "description", NULL },
236 .local_name = "group",
237 .remote_name = "posixGroup",
238 .base_classes = { "top", NULL },
239 .musts = { "cn", "gidNumber", NULL },
240 .mays = { "userPassword", "memberUid", "description", NULL },
243 .local_name = "group",
244 .remote_name = "sambaGroupMapping",
245 .base_classes = { "top", "posixGroup", NULL },
246 .musts = { "gidNumber", "sambaSID", "sambaGroupType", NULL },
247 .mays = { "displayName", "description", "sambaSIDList", NULL },
250 .local_name = "user",
251 .remote_name = "sambaSAMAccount",
252 .base_classes = { "top", "posixAccount", NULL },
253 .musts = { "uid", "sambaSID", NULL },
254 .mays = { "cn", "sambaLMPassword", "sambaNTPassword",
255 "sambaPwdLastSet", "sambaLogonTime", "sambaLogoffTime",
256 "sambaKickoffTime", "sambaPwdCanChange", "sambaPwdMustChange",
257 "sambaAcctFlags", "displayName", "sambaHomePath", "sambaHomeDrive",
258 "sambaLogonScript", "sambaProfilePath", "description", "sambaUserWorkstations",
259 "sambaPrimaryGroupSID", "sambaDomainName", "sambaMungedDial",
260 "sambaBadPasswordCount", "sambaBadPasswordTime",
261 "sambaPasswordHistory", "sambaLogonHours", NULL }
265 .local_name = "domain",
266 .remote_name = "sambaDomain",
267 .base_classes = { "top", NULL },
268 .musts = { "sambaDomainName", "sambaSID", NULL },
269 .mays = { "sambaNextRid", "sambaNextGroupRid", "sambaNextUserRid", "sambaAlgorithmicRidBase", NULL },
274 const struct ldb_map_attribute samba3_attributes[] =
276 /* sambaNextRid -> nextRid */
278 .local_name = "nextRid",
282 .remote_name = "sambaNextRid",
287 /* sambaBadPasswordTime -> badPasswordtime*/
289 .local_name = "badPasswordTime",
293 .remote_name = "sambaBadPasswordTime",
298 /* sambaLMPassword -> lmPwdHash*/
300 .local_name = "lmPwdHash",
304 .remote_name = "sambaLMPassword",
309 /* sambaGroupType -> groupType */
311 .local_name = "groupType",
315 .remote_name = "sambaGroupType",
320 /* sambaNTPassword -> ntPwdHash*/
322 .local_name = "ntPwdHash",
326 .remote_name = "sambaNTPassword",
331 /* sambaPrimaryGroupSID -> primaryGroupID */
333 .local_name = "primaryGroupID",
334 .type = MAP_GENERATE,
337 .remote_names = { "sambaPrimaryGroupSID", NULL },
338 .generate_local = generate_primaryGroupID,
339 .generate_remote = generate_sambaPrimaryGroupSID,
344 /* sambaBadPasswordCount -> badPwdCount */
346 .local_name = "badPwdCount",
350 .remote_name = "sambaBadPasswordCount",
355 /* sambaLogonTime -> lastLogon*/
357 .local_name = "lastLogon",
361 .remote_name = "sambaLogonTime",
366 /* sambaLogoffTime -> lastLogoff*/
368 .local_name = "lastLogoff",
372 .remote_name = "sambaLogoffTime",
377 /* uid -> unixName */
379 .local_name = "unixName",
383 .remote_name = "uid",
388 /* displayName -> name */
390 .local_name = "name",
394 .remote_name = "displayName",
405 /* sAMAccountName -> cn */
407 .local_name = "sAMAccountName",
411 .remote_name = "uid",
412 .convert_remote = convert_uid_samaccount,
419 .local_name = "objectCategory",
425 .local_name = "objectGUID",
431 .local_name = "objectVersion",
437 .local_name = "codePage",
443 .local_name = "dNSHostName",
450 .local_name = "dnsDomain",
456 .local_name = "dnsRoot",
462 .local_name = "countryCode",
468 .local_name = "nTMixedDomain",
472 /* operatingSystem */
474 .local_name = "operatingSystem",
478 /* operatingSystemVersion */
480 .local_name = "operatingSystemVersion",
485 /* servicePrincipalName */
487 .local_name = "servicePrincipalName",
491 /* msDS-Behavior-Version */
493 .local_name = "msDS-Behavior-Version",
497 /* msDS-KeyVersionNumber */
499 .local_name = "msDS-KeyVersionNumber",
503 /* msDs-masteredBy */
505 .local_name = "msDs-masteredBy",
523 .local_name = "description",
527 /* sambaSID -> objectSid*/
529 .local_name = "objectSid",
533 .remote_name = "sambaSID",
534 .convert_local = decode_sid,
535 .convert_remote = encode_sid,
540 /* sambaPwdLastSet -> pwdLastSet */
542 .local_name = "pwdLastSet",
546 .remote_name = "sambaPwdLastSet",
553 .local_name = "accountExpires",
559 .local_name = "adminCount",
565 .local_name = "canonicalName",
569 /* createTimestamp */
571 .local_name = "createTimestamp",
577 .local_name = "creationTime",
583 .local_name = "dMDLocation",
589 .local_name = "fSMORoleOwner",
595 .local_name = "forceLogoff",
601 .local_name = "instanceType",
607 .local_name = "invocationId",
611 /* isCriticalSystemObject */
613 .local_name = "isCriticalSystemObject",
617 /* localPolicyFlags */
619 .local_name = "localPolicyFlags",
623 /* lockOutObservationWindow */
625 .local_name = "lockOutObservationWindow",
629 /* lockoutDuration */
631 .local_name = "lockoutDuration",
635 /* lockoutThreshold */
637 .local_name = "lockoutThreshold",
643 .local_name = "logonCount",
649 .local_name = "masteredBy",
655 .local_name = "maxPwdAge",
661 .local_name = "member",
667 .local_name = "memberOf",
673 .local_name = "minPwdAge",
679 .local_name = "minPwdLength",
685 .local_name = "modifiedCount",
689 /* modifiedCountAtLastProm */
691 .local_name = "modifiedCountAtLastProm",
695 /* modifyTimestamp */
697 .local_name = "modifyTimestamp",
703 .local_name = "nCName",
709 .local_name = "nETBIOSName",
715 .local_name = "oEMInformation",
721 .local_name = "privilege",
725 /* pwdHistoryLength */
727 .local_name = "pwdHistoryLength",
733 .local_name = "pwdProperties",
737 /* rIDAvailablePool */
739 .local_name = "rIDAvailablePool",
745 .local_name = "revision",
749 /* ridManagerReference */
751 .local_name = "ridManagerReference",
757 .local_name = "sAMAccountType",
763 .local_name = "sPNMappings",
767 /* serverReference */
769 .local_name = "serverReference",
775 .local_name = "serverState",
779 /* showInAdvancedViewOnly */
781 .local_name = "showInAdvancedViewOnly",
787 .local_name = "subRefs",
793 .local_name = "systemFlags",
799 .local_name = "uASCompat",
805 .local_name = "uSNChanged",
811 .local_name = "uSNCreated",
817 .local_name = "sambaPassword",
821 /* userAccountControl */
823 .local_name = "userAccountControl",
829 .local_name = "whenChanged",
835 .local_name = "whenCreated",
841 .local_name = "unixName",
845 .remote_name = "uidNumber",
846 .convert_local = lookup_uid,
851 /* gidNumber. Perhaps make into generate so we can distinguish between
852 * groups and accounts? */
854 .local_name = "unixName",
858 .remote_name = "gidNumber",
859 .convert_local = lookup_gid,
866 .local_name = "unixName",
870 .remote_name = "homeDirectory",
871 .convert_local = lookup_homedir,
880 /* the init function */
881 struct ldb_module *ldb_samba3sam_module_init(struct ldb_context *ldb, const char *options[])
883 return ldb_map_init(ldb, samba3_attributes, samba3_objectclasses, "samba3sam");