2 ldb database library - Samba3 SAM compatibility backend
4 Copyright (C) Jelmer Vernooij 2005
8 #include "ldb/include/ldb.h"
9 #include "ldb/include/ldb_private.h"
10 #include "ldb/include/ldb_errors.h"
11 #include "ldb/modules/ldb_map.h"
12 #include "system/passwd.h"
14 #include "librpc/gen_ndr/ndr_security.h"
15 #include "librpc/ndr/libndr.h"
16 #include "libcli/security/security.h"
17 #include "libcli/security/proto.h"
20 * sambaSID -> member (dn!)
21 * sambaSIDList -> member (dn!)
22 * sambaDomainName -> name
28 * sambaAcctFlags -> systemFlags ?
29 * sambaPasswordHistory -> ntPwdHistory*/
37 * sambaAlgorithmicRidBase
48 * sambaUserWorkstations
52 /* In Samba4 but not in Samba3:
55 static struct ldb_message_element *generate_primaryGroupID(struct ldb_module *module, TALLOC_CTX *ctx, const char *attr, const struct ldb_message *remote)
57 struct ldb_message_element *el;
58 const char *sid = ldb_msg_find_attr_as_string(remote, attr, NULL);
63 if (strchr(sid, '-') == NULL)
66 el = talloc_zero(ctx, struct ldb_message_element);
67 el->name = talloc_strdup(ctx, "primaryGroupID");
69 el->values = talloc_array(ctx, struct ldb_val, 1);
70 el->values[0].data = (uint8_t *)talloc_strdup(ctx, strchr(sid, '-')+1);
71 el->values[0].length = strlen((char *)el->values[0].data);
76 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)
78 const struct ldb_val *sidval;
83 sidval = ldb_msg_find_ldb_val(local, "objectSid");
86 return; /* Sorry, no SID today.. */
88 sid = talloc(remote_mp, struct dom_sid);
92 status = ndr_pull_struct_blob(sidval, sid, sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
93 if (!NT_STATUS_IS_OK(status)) {
98 if (!ldb_msg_find_ldb_val(local, "primaryGroupID"))
99 return; /* Sorry, no SID today.. */
103 sidstring = dom_sid_string(remote_mp, sid);
105 ldb_msg_add_fmt(remote_mp, "sambaPrimaryGroupSID", "%s-%d", sidstring, ldb_msg_find_attr_as_uint(local, "primaryGroupID", 0));
106 talloc_free(sidstring);
109 static struct ldb_val convert_uid_samaccount(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
111 return ldb_val_dup(ctx, val);
114 static struct ldb_val lookup_homedir(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
117 struct ldb_val retval;
119 pwd = getpwnam((char *)val->data);
122 ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Unable to lookup '%s' in passwd", (char *)val->data);
123 return *talloc_zero(ctx, struct ldb_val);
126 retval.data = (uint8_t *)talloc_strdup(ctx, pwd->pw_dir);
127 retval.length = strlen((char *)retval.data);
132 static struct ldb_val lookup_gid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
135 struct ldb_val retval;
137 pwd = getpwnam((char *)val->data);
140 return *talloc_zero(ctx, struct ldb_val);
143 retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_gid);
144 retval.length = strlen((char *)retval.data);
149 static struct ldb_val lookup_uid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
152 struct ldb_val retval;
154 pwd = getpwnam((char *)val->data);
157 return *talloc_zero(ctx, struct ldb_val);
160 retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_uid);
161 retval.length = strlen((char *)retval.data);
166 static struct ldb_val encode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
168 struct dom_sid *sid = dom_sid_parse_talloc(ctx, (char *)val->data);
169 struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
175 status = ndr_push_struct_blob(out, ctx, sid,
176 (ndr_push_flags_fn_t)ndr_push_dom_sid);
178 if (!NT_STATUS_IS_OK(status)) {
185 static struct ldb_val decode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
189 struct ldb_val *out = talloc_zero(ctx, struct ldb_val);
191 sid = talloc(ctx, struct dom_sid);
195 status = ndr_pull_struct_blob(val, sid, sid,
196 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
197 if (!NT_STATUS_IS_OK(status)) {
201 out->data = (uint8_t *)dom_sid_string(ctx, sid);
203 if (out->data == NULL) {
206 out->length = strlen((const char *)out->data);
211 const struct ldb_map_objectclass samba3_objectclasses[] = {
213 .local_name = "user",
214 .remote_name = "posixAccount",
215 .base_classes = { "top", NULL },
216 .musts = { "cn", "uid", "uidNumber", "gidNumber", "homeDirectory", NULL },
217 .mays = { "userPassword", "loginShell", "gecos", "description", NULL },
220 .local_name = "group",
221 .remote_name = "posixGroup",
222 .base_classes = { "top", NULL },
223 .musts = { "cn", "gidNumber", NULL },
224 .mays = { "userPassword", "memberUid", "description", NULL },
227 .local_name = "group",
228 .remote_name = "sambaGroupMapping",
229 .base_classes = { "top", "posixGroup", NULL },
230 .musts = { "gidNumber", "sambaSID", "sambaGroupType", NULL },
231 .mays = { "displayName", "description", "sambaSIDList", NULL },
234 .local_name = "user",
235 .remote_name = "sambaSAMAccount",
236 .base_classes = { "top", "posixAccount", NULL },
237 .musts = { "uid", "sambaSID", NULL },
238 .mays = { "cn", "sambaLMPassword", "sambaNTPassword",
239 "sambaPwdLastSet", "sambaLogonTime", "sambaLogoffTime",
240 "sambaKickoffTime", "sambaPwdCanChange", "sambaPwdMustChange",
241 "sambaAcctFlags", "displayName", "sambaHomePath", "sambaHomeDrive",
242 "sambaLogonScript", "sambaProfilePath", "description", "sambaUserWorkstations",
243 "sambaPrimaryGroupSID", "sambaDomainName", "sambaMungedDial",
244 "sambaBadPasswordCount", "sambaBadPasswordTime",
245 "sambaPasswordHistory", "sambaLogonHours", NULL }
249 .local_name = "domain",
250 .remote_name = "sambaDomain",
251 .base_classes = { "top", NULL },
252 .musts = { "sambaDomainName", "sambaSID", NULL },
253 .mays = { "sambaNextRid", "sambaNextGroupRid", "sambaNextUserRid", "sambaAlgorithmicRidBase", NULL },
258 const struct ldb_map_attribute samba3_attributes[] =
260 /* sambaNextRid -> nextRid */
262 .local_name = "nextRid",
266 .remote_name = "sambaNextRid",
271 /* sambaBadPasswordTime -> badPasswordtime*/
273 .local_name = "badPasswordTime",
277 .remote_name = "sambaBadPasswordTime",
282 /* sambaLMPassword -> lmPwdHash*/
284 .local_name = "lmPwdHash",
288 .remote_name = "sambaLMPassword",
293 /* sambaGroupType -> groupType */
295 .local_name = "groupType",
299 .remote_name = "sambaGroupType",
304 /* sambaNTPassword -> ntPwdHash*/
306 .local_name = "ntPwdHash",
310 .remote_name = "sambaNTPassword",
315 /* sambaPrimaryGroupSID -> primaryGroupID */
317 .local_name = "primaryGroupID",
318 .type = MAP_GENERATE,
321 .remote_names = { "sambaPrimaryGroupSID", NULL },
322 .generate_local = generate_primaryGroupID,
323 .generate_remote = generate_sambaPrimaryGroupSID,
328 /* sambaBadPasswordCount -> badPwdCount */
330 .local_name = "badPwdCount",
334 .remote_name = "sambaBadPasswordCount",
339 /* sambaLogonTime -> lastLogon*/
341 .local_name = "lastLogon",
345 .remote_name = "sambaLogonTime",
350 /* sambaLogoffTime -> lastLogoff*/
352 .local_name = "lastLogoff",
356 .remote_name = "sambaLogoffTime",
361 /* uid -> unixName */
363 .local_name = "unixName",
367 .remote_name = "uid",
372 /* displayName -> name */
374 .local_name = "name",
378 .remote_name = "displayName",
389 /* sAMAccountName -> cn */
391 .local_name = "sAMAccountName",
395 .remote_name = "uid",
396 .convert_remote = convert_uid_samaccount,
403 .local_name = "objectCategory",
409 .local_name = "objectGUID",
415 .local_name = "objectVersion",
421 .local_name = "codePage",
427 .local_name = "dNSHostName",
434 .local_name = "dnsDomain",
440 .local_name = "dnsRoot",
446 .local_name = "countryCode",
452 .local_name = "nTMixedDomain",
456 /* operatingSystem */
458 .local_name = "operatingSystem",
462 /* operatingSystemVersion */
464 .local_name = "operatingSystemVersion",
469 /* servicePrincipalName */
471 .local_name = "servicePrincipalName",
475 /* msDS-Behavior-Version */
477 .local_name = "msDS-Behavior-Version",
481 /* msDS-KeyVersionNumber */
483 .local_name = "msDS-KeyVersionNumber",
487 /* msDs-masteredBy */
489 .local_name = "msDs-masteredBy",
507 .local_name = "description",
511 /* sambaSID -> objectSid*/
513 .local_name = "objectSid",
517 .remote_name = "sambaSID",
518 .convert_local = decode_sid,
519 .convert_remote = encode_sid,
524 /* sambaPwdLastSet -> pwdLastSet */
526 .local_name = "pwdLastSet",
530 .remote_name = "sambaPwdLastSet",
537 .local_name = "accountExpires",
543 .local_name = "adminCount",
549 .local_name = "canonicalName",
553 /* createTimestamp */
555 .local_name = "createTimestamp",
561 .local_name = "creationTime",
567 .local_name = "dMDLocation",
573 .local_name = "fSMORoleOwner",
579 .local_name = "forceLogoff",
585 .local_name = "instanceType",
591 .local_name = "invocationId",
595 /* isCriticalSystemObject */
597 .local_name = "isCriticalSystemObject",
601 /* localPolicyFlags */
603 .local_name = "localPolicyFlags",
607 /* lockOutObservationWindow */
609 .local_name = "lockOutObservationWindow",
613 /* lockoutDuration */
615 .local_name = "lockoutDuration",
619 /* lockoutThreshold */
621 .local_name = "lockoutThreshold",
627 .local_name = "logonCount",
633 .local_name = "masteredBy",
639 .local_name = "maxPwdAge",
645 .local_name = "member",
651 .local_name = "memberOf",
657 .local_name = "minPwdAge",
663 .local_name = "minPwdLength",
669 .local_name = "modifiedCount",
673 /* modifiedCountAtLastProm */
675 .local_name = "modifiedCountAtLastProm",
679 /* modifyTimestamp */
681 .local_name = "modifyTimestamp",
687 .local_name = "nCName",
693 .local_name = "nETBIOSName",
699 .local_name = "oEMInformation",
705 .local_name = "privilege",
709 /* pwdHistoryLength */
711 .local_name = "pwdHistoryLength",
717 .local_name = "pwdProperties",
721 /* rIDAvailablePool */
723 .local_name = "rIDAvailablePool",
729 .local_name = "revision",
733 /* ridManagerReference */
735 .local_name = "ridManagerReference",
741 .local_name = "sAMAccountType",
747 .local_name = "sPNMappings",
751 /* serverReference */
753 .local_name = "serverReference",
759 .local_name = "serverState",
763 /* showInAdvancedViewOnly */
765 .local_name = "showInAdvancedViewOnly",
771 .local_name = "subRefs",
777 .local_name = "systemFlags",
783 .local_name = "uASCompat",
789 .local_name = "uSNChanged",
795 .local_name = "uSNCreated",
801 .local_name = "sambaPassword",
805 /* userAccountControl */
807 .local_name = "userAccountControl",
813 .local_name = "whenChanged",
819 .local_name = "whenCreated",
825 .local_name = "unixName",
829 .remote_name = "uidNumber",
830 .convert_local = lookup_uid,
835 /* gidNumber. Perhaps make into generate so we can distinguish between
836 * groups and accounts? */
838 .local_name = "unixName",
842 .remote_name = "gidNumber",
843 .convert_local = lookup_gid,
850 .local_name = "unixName",
854 .remote_name = "homeDirectory",
855 .convert_local = lookup_homedir,
864 /* the context init function */
865 static int samba3sam_init(struct ldb_module *module)
869 ret = ldb_map_init(module, samba3_attributes, samba3_objectclasses, "samba3sam");
870 if (ret != LDB_SUCCESS)
873 return ldb_next_init(module);
876 static struct ldb_module_ops samba3sam_ops = {
878 .init_context = samba3sam_init,
881 /* the init function */
882 int ldb_samba3sam_module_init(void)
884 struct ldb_module_ops ops = ldb_map_get_ops();
885 samba3sam_ops.add = ops.add;
886 samba3sam_ops.modify = ops.modify;
887 samba3sam_ops.del = ops.del;
888 samba3sam_ops.rename = ops.rename;
889 samba3sam_ops.search = ops.search;
890 samba3sam_ops.wait = ops.wait;
892 return ldb_register_module(&samba3sam_ops);