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 struct ldb_message_element *generate_primaryGroupID(struct ldb_module *module, TALLOC_CTX *ctx, const char *attr, const struct ldb_message *remote)
51 struct ldb_message_element *el;
52 const char *sid = ldb_msg_find_attr_as_string(remote, attr, NULL);
57 if (strchr(sid, '-') == NULL)
60 el = talloc_zero(ctx, struct ldb_message_element);
61 el->name = talloc_strdup(ctx, "primaryGroupID");
63 el->values = talloc_array(ctx, struct ldb_val, 1);
64 el->values[0].data = (uint8_t *)talloc_strdup(ctx, strchr(sid, '-')+1);
65 el->values[0].length = strlen((char *)el->values[0].data);
70 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)
72 const struct ldb_val *sidval;
77 sidval = ldb_msg_find_ldb_val(local, "objectSid");
80 return; /* Sorry, no SID today.. */
82 sid = talloc(remote_mp, struct dom_sid);
86 status = ndr_pull_struct_blob(sidval, sid, sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
87 if (!NT_STATUS_IS_OK(status)) {
92 if (!ldb_msg_find_ldb_val(local, "primaryGroupID"))
93 return; /* Sorry, no SID today.. */
97 sidstring = dom_sid_string(remote_mp, sid);
99 ldb_msg_add_fmt(remote_mp, "sambaPrimaryGroupSID", "%s-%d", sidstring, ldb_msg_find_attr_as_uint(local, "primaryGroupID", 0));
100 talloc_free(sidstring);
103 static struct ldb_val convert_uid_samaccount(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
105 return ldb_val_dup(ctx, val);
108 static struct ldb_val lookup_homedir(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
111 struct ldb_val retval;
113 pwd = getpwnam((char *)val->data);
116 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Unable to lookup '%s' in passwd", (char *)val->data);
117 return *talloc_zero(ctx, struct ldb_val);
120 retval.data = (uint8_t *)talloc_strdup(ctx, pwd->pw_dir);
121 retval.length = strlen((char *)retval.data);
126 static struct ldb_val lookup_gid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
129 struct ldb_val retval;
131 pwd = getpwnam((char *)val->data);
134 return *talloc_zero(ctx, struct ldb_val);
137 retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_gid);
138 retval.length = strlen((char *)retval.data);
143 static struct ldb_val lookup_uid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
146 struct ldb_val retval;
148 pwd = getpwnam((char *)val->data);
151 return *talloc_zero(ctx, struct ldb_val);
154 retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_uid);
155 retval.length = strlen((char *)retval.data);
160 static struct ldb_val encode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
162 struct dom_sid *sid = dom_sid_parse_talloc(ctx, (char *)val->data);
163 struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
169 status = ndr_push_struct_blob(out, ctx, sid,
170 (ndr_push_flags_fn_t)ndr_push_dom_sid);
172 if (!NT_STATUS_IS_OK(status)) {
179 static struct ldb_val decode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
183 struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
185 sid = talloc(ctx, struct dom_sid);
189 status = ndr_pull_struct_blob(val, sid, sid,
190 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
191 if (!NT_STATUS_IS_OK(status)) {
195 out->data = (uint8_t *)dom_sid_string(ctx, sid);
197 if (out->data == NULL) {
200 out->length = strlen((const char *)out->data);
205 const struct ldb_map_objectclass samba3_objectclasses[] = {
207 .local_name = "user",
208 .remote_name = "posixAccount",
209 .base_classes = { "top", NULL },
210 .musts = { "cn", "uid", "uidNumber", "gidNumber", "homeDirectory", NULL },
211 .mays = { "userPassword", "loginShell", "gecos", "description", NULL },
214 .local_name = "group",
215 .remote_name = "posixGroup",
216 .base_classes = { "top", NULL },
217 .musts = { "cn", "gidNumber", NULL },
218 .mays = { "userPassword", "memberUid", "description", NULL },
221 .local_name = "group",
222 .remote_name = "sambaGroupMapping",
223 .base_classes = { "top", "posixGroup", NULL },
224 .musts = { "gidNumber", "sambaSID", "sambaGroupType", NULL },
225 .mays = { "displayName", "description", "sambaSIDList", NULL },
228 .local_name = "user",
229 .remote_name = "sambaSAMAccount",
230 .base_classes = { "top", "posixAccount", NULL },
231 .musts = { "uid", "sambaSID", NULL },
232 .mays = { "cn", "sambaLMPassword", "sambaNTPassword",
233 "sambaPwdLastSet", "sambaLogonTime", "sambaLogoffTime",
234 "sambaKickoffTime", "sambaPwdCanChange", "sambaPwdMustChange",
235 "sambaAcctFlags", "displayName", "sambaHomePath", "sambaHomeDrive",
236 "sambaLogonScript", "sambaProfilePath", "description", "sambaUserWorkstations",
237 "sambaPrimaryGroupSID", "sambaDomainName", "sambaMungedDial",
238 "sambaBadPasswordCount", "sambaBadPasswordTime",
239 "sambaPasswordHistory", "sambaLogonHours", NULL }
243 .local_name = "domain",
244 .remote_name = "sambaDomain",
245 .base_classes = { "top", NULL },
246 .musts = { "sambaDomainName", "sambaSID", NULL },
247 .mays = { "sambaNextRid", "sambaNextGroupRid", "sambaNextUserRid", "sambaAlgorithmicRidBase", NULL },
252 const struct ldb_map_attribute samba3_attributes[] =
254 /* sambaNextRid -> nextRid */
256 .local_name = "nextRid",
260 .remote_name = "sambaNextRid",
265 /* sambaBadPasswordTime -> badPasswordtime*/
267 .local_name = "badPasswordTime",
271 .remote_name = "sambaBadPasswordTime",
276 /* sambaLMPassword -> lmPwdHash*/
278 .local_name = "lmPwdHash",
282 .remote_name = "sambaLMPassword",
287 /* sambaGroupType -> groupType */
289 .local_name = "groupType",
293 .remote_name = "sambaGroupType",
298 /* sambaNTPassword -> ntPwdHash*/
300 .local_name = "ntPwdHash",
304 .remote_name = "sambaNTPassword",
309 /* sambaPrimaryGroupSID -> primaryGroupID */
311 .local_name = "primaryGroupID",
312 .type = MAP_GENERATE,
315 .remote_names = { "sambaPrimaryGroupSID", NULL },
316 .generate_local = generate_primaryGroupID,
317 .generate_remote = generate_sambaPrimaryGroupSID,
322 /* sambaBadPasswordCount -> badPwdCount */
324 .local_name = "badPwdCount",
328 .remote_name = "sambaBadPasswordCount",
333 /* sambaLogonTime -> lastLogon*/
335 .local_name = "lastLogon",
339 .remote_name = "sambaLogonTime",
344 /* sambaLogoffTime -> lastLogoff*/
346 .local_name = "lastLogoff",
350 .remote_name = "sambaLogoffTime",
355 /* uid -> unixName */
357 .local_name = "unixName",
361 .remote_name = "uid",
366 /* displayName -> name */
368 .local_name = "name",
372 .remote_name = "displayName",
383 /* sAMAccountName -> cn */
385 .local_name = "sAMAccountName",
389 .remote_name = "uid",
390 .convert_remote = convert_uid_samaccount,
397 .local_name = "objectCategory",
403 .local_name = "objectGUID",
409 .local_name = "objectVersion",
415 .local_name = "codePage",
421 .local_name = "dNSHostName",
428 .local_name = "dnsDomain",
434 .local_name = "dnsRoot",
440 .local_name = "countryCode",
446 .local_name = "nTMixedDomain",
450 /* operatingSystem */
452 .local_name = "operatingSystem",
456 /* operatingSystemVersion */
458 .local_name = "operatingSystemVersion",
463 /* servicePrincipalName */
465 .local_name = "servicePrincipalName",
469 /* msDS-Behavior-Version */
471 .local_name = "msDS-Behavior-Version",
475 /* msDS-KeyVersionNumber */
477 .local_name = "msDS-KeyVersionNumber",
481 /* msDs-masteredBy */
483 .local_name = "msDs-masteredBy",
501 .local_name = "description",
505 /* sambaSID -> objectSid*/
507 .local_name = "objectSid",
511 .remote_name = "sambaSID",
512 .convert_local = decode_sid,
513 .convert_remote = encode_sid,
518 /* sambaPwdLastSet -> pwdLastSet */
520 .local_name = "pwdLastSet",
524 .remote_name = "sambaPwdLastSet",
531 .local_name = "accountExpires",
537 .local_name = "adminCount",
543 .local_name = "canonicalName",
547 /* createTimestamp */
549 .local_name = "createTimestamp",
555 .local_name = "creationTime",
561 .local_name = "dMDLocation",
567 .local_name = "fSMORoleOwner",
573 .local_name = "forceLogoff",
579 .local_name = "instanceType",
585 .local_name = "invocationId",
589 /* isCriticalSystemObject */
591 .local_name = "isCriticalSystemObject",
595 /* localPolicyFlags */
597 .local_name = "localPolicyFlags",
601 /* lockOutObservationWindow */
603 .local_name = "lockOutObservationWindow",
607 /* lockoutDuration */
609 .local_name = "lockoutDuration",
613 /* lockoutThreshold */
615 .local_name = "lockoutThreshold",
621 .local_name = "logonCount",
627 .local_name = "masteredBy",
633 .local_name = "maxPwdAge",
639 .local_name = "member",
645 .local_name = "memberOf",
651 .local_name = "minPwdAge",
657 .local_name = "minPwdLength",
663 .local_name = "modifiedCount",
667 /* modifiedCountAtLastProm */
669 .local_name = "modifiedCountAtLastProm",
673 /* modifyTimestamp */
675 .local_name = "modifyTimestamp",
681 .local_name = "nCName",
687 .local_name = "nETBIOSName",
693 .local_name = "oEMInformation",
699 .local_name = "privilege",
703 /* pwdHistoryLength */
705 .local_name = "pwdHistoryLength",
711 .local_name = "pwdProperties",
715 /* rIDAvailablePool */
717 .local_name = "rIDAvailablePool",
723 .local_name = "revision",
727 /* ridManagerReference */
729 .local_name = "ridManagerReference",
735 .local_name = "sAMAccountType",
741 .local_name = "sPNMappings",
745 /* serverReference */
747 .local_name = "serverReference",
753 .local_name = "serverState",
757 /* showInAdvancedViewOnly */
759 .local_name = "showInAdvancedViewOnly",
765 .local_name = "subRefs",
771 .local_name = "systemFlags",
777 .local_name = "uASCompat",
783 .local_name = "uSNChanged",
789 .local_name = "uSNCreated",
795 .local_name = "sambaPassword",
799 /* userAccountControl */
801 .local_name = "userAccountControl",
807 .local_name = "whenChanged",
813 .local_name = "whenCreated",
819 .local_name = "unixName",
823 .remote_name = "uidNumber",
824 .convert_local = lookup_uid,
829 /* gidNumber. Perhaps make into generate so we can distinguish between
830 * groups and accounts? */
832 .local_name = "unixName",
836 .remote_name = "gidNumber",
837 .convert_local = lookup_gid,
844 .local_name = "unixName",
848 .remote_name = "homeDirectory",
849 .convert_local = lookup_homedir,
858 /* the init function */
859 int ldb_samba3sam_module_init(void)
861 return ldb_map_init(ldb, samba3_attributes, samba3_objectclasses, "samba3sam");