2
ldb database library - Samba3 SAM compatibility backend
4
Copyright (C) Jelmer Vernooij 2005
5
Copyright (C) Martin Kuehl <mkhl@samba.org> 2006
9
#include "ldb_module.h"
10
#include "ldb/ldb_map/ldb_map.h"
11
#include "system/passwd.h"
13
#include "librpc/gen_ndr/ndr_security.h"
14
#include "librpc/gen_ndr/ndr_samr.h"
15
#include "librpc/ndr/libndr.h"
16
#include "libcli/security/security.h"
17
#include "libcli/security/proto.h"
18
#include "lib/samba3/samba3.h"
21
* sambaSID -> member (dn!)
22
* sambaSIDList -> member (dn!)
23
* sambaDomainName -> name
29
* sambaAcctFlags -> systemFlags ?
30
* sambaPasswordHistory -> ntPwdHistory*/
38
* sambaAlgorithmicRidBase
49
* sambaUserWorkstations
53
/* In Samba4 but not in Samba3:
56
/* From a sambaPrimaryGroupSID, generate a primaryGroupID (integer) attribute */
57
static struct ldb_message_element *generate_primaryGroupID(struct ldb_module *module, TALLOC_CTX *ctx, const char *local_attr, const struct ldb_message *remote)
59
struct ldb_message_element *el;
60
const char *sid = ldb_msg_find_attr_as_string(remote, "sambaPrimaryGroupSID", NULL);
66
p = strrchr(sid, '-');
70
el = talloc_zero(ctx, struct ldb_message_element);
71
el->name = talloc_strdup(ctx, "primaryGroupID");
73
el->values = talloc_array(ctx, struct ldb_val, 1);
74
el->values[0].data = (uint8_t *)talloc_strdup(el->values, p+1);
75
el->values[0].length = strlen((char *)el->values[0].data);
80
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)
82
const struct ldb_val *sidval;
85
enum ndr_err_code ndr_err;
87
/* We need the domain, so we get it from the objectSid that we hope is here... */
88
sidval = ldb_msg_find_ldb_val(local, "objectSid");
91
return; /* Sorry, no SID today.. */
93
sid = talloc(remote_mp, struct dom_sid);
98
ndr_err = ndr_pull_struct_blob(sidval, sid, NULL, sid, (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
99
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
104
if (!ldb_msg_find_ldb_val(local, "primaryGroupID"))
105
return; /* Sorry, no SID today.. */
109
sidstring = dom_sid_string(remote_mp, sid);
111
ldb_msg_add_fmt(remote_mp, "sambaPrimaryGroupSID", "%s-%d", sidstring, ldb_msg_find_attr_as_uint(local, "primaryGroupID", 0));
112
talloc_free(sidstring);
115
/* Just copy the old value. */
116
static struct ldb_val convert_uid_samaccount(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
118
struct ldb_val out = data_blob(NULL, 0);
119
out = ldb_val_dup(ctx, val);
124
static struct ldb_val lookup_homedir(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
126
struct ldb_context *ldb;
128
struct ldb_val retval;
130
ldb = ldb_module_get_ctx(module);
132
pwd = getpwnam((char *)val->data);
135
ldb_debug(ldb, LDB_DEBUG_WARNING, "Unable to lookup '%s' in passwd", (char *)val->data);
136
return *talloc_zero(ctx, struct ldb_val);
139
retval.data = (uint8_t *)talloc_strdup(ctx, pwd->pw_dir);
140
retval.length = strlen((char *)retval.data);
145
static struct ldb_val lookup_gid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
148
struct ldb_val retval;
150
pwd = getpwnam((char *)val->data);
153
return *talloc_zero(ctx, struct ldb_val);
156
retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_gid);
157
retval.length = strlen((char *)retval.data);
162
static struct ldb_val lookup_uid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
165
struct ldb_val retval;
167
pwd = getpwnam((char *)val->data);
170
return *talloc_zero(ctx, struct ldb_val);
173
retval.data = (uint8_t *)talloc_asprintf(ctx, "%ld", (unsigned long)pwd->pw_uid);
174
retval.length = strlen((char *)retval.data);
179
/* Encode a sambaSID to an objectSid. */
180
static struct ldb_val encode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
182
struct ldb_val out = data_blob(NULL, 0);
184
enum ndr_err_code ndr_err;
186
sid = dom_sid_parse_talloc(ctx, (char *)val->data);
191
ndr_err = ndr_push_struct_blob(&out, ctx,
193
sid, (ndr_push_flags_fn_t)ndr_push_dom_sid);
195
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
202
/* Decode an objectSid to a sambaSID. */
203
static struct ldb_val decode_sid(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
205
struct ldb_val out = data_blob(NULL, 0);
207
enum ndr_err_code ndr_err;
209
sid = talloc(ctx, struct dom_sid);
214
ndr_err = ndr_pull_struct_blob(val, sid, NULL, sid,
215
(ndr_pull_flags_fn_t)ndr_pull_dom_sid);
216
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
220
out.data = (uint8_t *)dom_sid_string(ctx, sid);
221
if (out.data == NULL) {
224
out.length = strlen((const char *)out.data);
231
/* Convert 16 bytes to 32 hex digits. */
232
static struct ldb_val bin2hex(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
235
struct samr_Password pwd;
236
if (val->length != sizeof(pwd.hash)) {
237
return data_blob(NULL, 0);
239
memcpy(pwd.hash, val->data, sizeof(pwd.hash));
240
out = data_blob_string_const(smbpasswd_sethexpwd(ctx, &pwd, 0));
242
return data_blob(NULL, 0);
247
/* Convert 32 hex digits to 16 bytes. */
248
static struct ldb_val hex2bin(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
251
struct samr_Password *pwd;
252
pwd = smbpasswd_gethexpwd(ctx, (const char *)val->data);
254
return data_blob(NULL, 0);
256
out = data_blob_talloc(ctx, pwd->hash, sizeof(pwd->hash));
260
const struct ldb_map_objectclass samba3_objectclasses[] = {
262
.local_name = "user",
263
.remote_name = "posixAccount",
264
.base_classes = { "top", NULL },
265
.musts = { "cn", "uid", "uidNumber", "gidNumber", "homeDirectory", NULL },
266
.mays = { "userPassword", "loginShell", "gecos", "description", NULL },
269
.local_name = "group",
270
.remote_name = "posixGroup",
271
.base_classes = { "top", NULL },
272
.musts = { "cn", "gidNumber", NULL },
273
.mays = { "userPassword", "memberUid", "description", NULL },
276
.local_name = "group",
277
.remote_name = "sambaGroupMapping",
278
.base_classes = { "top", "posixGroup", NULL },
279
.musts = { "gidNumber", "sambaSID", "sambaGroupType", NULL },
280
.mays = { "displayName", "description", "sambaSIDList", NULL },
283
.local_name = "user",
284
.remote_name = "sambaSAMAccount",
285
.base_classes = { "top", "posixAccount", NULL },
286
.musts = { "uid", "sambaSID", NULL },
287
.mays = { "cn", "sambaLMPassword", "sambaNTPassword",
288
"sambaPwdLastSet", "sambaLogonTime", "sambaLogoffTime",
289
"sambaKickoffTime", "sambaPwdCanChange", "sambaPwdMustChange",
290
"sambaAcctFlags", "displayName", "sambaHomePath", "sambaHomeDrive",
291
"sambaLogonScript", "sambaProfilePath", "description", "sambaUserWorkstations",
292
"sambaPrimaryGroupSID", "sambaDomainName", "sambaMungedDial",
293
"sambaBadPasswordCount", "sambaBadPasswordTime",
294
"sambaPasswordHistory", "sambaLogonHours", NULL }
298
.local_name = "domain",
299
.remote_name = "sambaDomain",
300
.base_classes = { "top", NULL },
301
.musts = { "sambaDomainName", "sambaSID", NULL },
302
.mays = { "sambaNextRid", "sambaNextGroupRid", "sambaNextUserRid", "sambaAlgorithmicRidBase", NULL },
307
const struct ldb_map_attribute samba3_attributes[] =
309
/* sambaNextRid -> nextRid */
311
.local_name = "nextRid",
315
.remote_name = "sambaNextRid",
320
/* sambaBadPasswordTime -> badPasswordtime*/
322
.local_name = "badPasswordTime",
326
.remote_name = "sambaBadPasswordTime",
331
/* sambaLMPassword -> lmPwdHash*/
333
.local_name = "dBCSPwd",
337
.remote_name = "sambaLMPassword",
338
.convert_local = bin2hex,
339
.convert_remote = hex2bin,
344
/* sambaGroupType -> groupType */
346
.local_name = "groupType",
350
.remote_name = "sambaGroupType",
355
/* sambaNTPassword -> ntPwdHash*/
357
.local_name = "ntpwdhash",
361
.remote_name = "sambaNTPassword",
362
.convert_local = bin2hex,
363
.convert_remote = hex2bin,
368
/* sambaPrimaryGroupSID -> primaryGroupID */
370
.local_name = "primaryGroupID",
371
.type = MAP_GENERATE,
374
.remote_names = { "sambaPrimaryGroupSID", NULL },
375
.generate_local = generate_primaryGroupID,
376
.generate_remote = generate_sambaPrimaryGroupSID,
381
/* sambaBadPasswordCount -> badPwdCount */
383
.local_name = "badPwdCount",
387
.remote_name = "sambaBadPasswordCount",
392
/* sambaLogonTime -> lastLogon*/
394
.local_name = "lastLogon",
398
.remote_name = "sambaLogonTime",
403
/* sambaLogoffTime -> lastLogoff*/
405
.local_name = "lastLogoff",
409
.remote_name = "sambaLogoffTime",
414
/* uid -> unixName */
416
.local_name = "unixName",
420
.remote_name = "uid",
425
/* displayName -> name */
427
.local_name = "name",
431
.remote_name = "displayName",
442
/* sAMAccountName -> cn */
444
.local_name = "sAMAccountName",
448
.remote_name = "uid",
449
.convert_remote = convert_uid_samaccount,
456
.local_name = "objectCategory",
462
.local_name = "objectGUID",
468
.local_name = "objectVersion",
474
.local_name = "codePage",
480
.local_name = "dNSHostName",
487
.local_name = "dnsDomain",
493
.local_name = "dnsRoot",
499
.local_name = "countryCode",
505
.local_name = "nTMixedDomain",
509
/* operatingSystem */
511
.local_name = "operatingSystem",
515
/* operatingSystemVersion */
517
.local_name = "operatingSystemVersion",
522
/* servicePrincipalName */
524
.local_name = "servicePrincipalName",
528
/* msDS-Behavior-Version */
530
.local_name = "msDS-Behavior-Version",
534
/* msDS-KeyVersionNumber */
536
.local_name = "msDS-KeyVersionNumber",
540
/* msDs-masteredBy */
542
.local_name = "msDs-masteredBy",
560
.local_name = "description",
564
/* sambaSID -> objectSid*/
566
.local_name = "objectSid",
570
.remote_name = "sambaSID",
571
.convert_local = decode_sid,
572
.convert_remote = encode_sid,
577
/* sambaPwdLastSet -> pwdLastSet */
579
.local_name = "pwdLastSet",
583
.remote_name = "sambaPwdLastSet",
590
.local_name = "accountExpires",
596
.local_name = "adminCount",
602
.local_name = "canonicalName",
606
/* createTimestamp */
608
.local_name = "createTimestamp",
614
.local_name = "creationTime",
620
.local_name = "dMDLocation",
626
.local_name = "fSMORoleOwner",
632
.local_name = "forceLogoff",
638
.local_name = "instanceType",
644
.local_name = "invocationId",
648
/* isCriticalSystemObject */
650
.local_name = "isCriticalSystemObject",
654
/* localPolicyFlags */
656
.local_name = "localPolicyFlags",
660
/* lockOutObservationWindow */
662
.local_name = "lockOutObservationWindow",
666
/* lockoutDuration */
668
.local_name = "lockoutDuration",
672
/* lockoutThreshold */
674
.local_name = "lockoutThreshold",
680
.local_name = "logonCount",
686
.local_name = "masteredBy",
692
.local_name = "maxPwdAge",
698
.local_name = "member",
704
.local_name = "memberOf",
710
.local_name = "minPwdAge",
716
.local_name = "minPwdLength",
722
.local_name = "modifiedCount",
726
/* modifiedCountAtLastProm */
728
.local_name = "modifiedCountAtLastProm",
732
/* modifyTimestamp */
734
.local_name = "modifyTimestamp",
740
.local_name = "nCName",
746
.local_name = "nETBIOSName",
752
.local_name = "oEMInformation",
758
.local_name = "privilege",
762
/* pwdHistoryLength */
764
.local_name = "pwdHistoryLength",
770
.local_name = "pwdProperties",
774
/* rIDAvailablePool */
776
.local_name = "rIDAvailablePool",
782
.local_name = "revision",
786
/* ridManagerReference */
788
.local_name = "ridManagerReference",
794
.local_name = "sAMAccountType",
800
.local_name = "sPNMappings",
804
/* serverReference */
806
.local_name = "serverReference",
812
.local_name = "serverState",
816
/* showInAdvancedViewOnly */
818
.local_name = "showInAdvancedViewOnly",
824
.local_name = "subRefs",
830
.local_name = "systemFlags",
836
.local_name = "uASCompat",
842
.local_name = "uSNChanged",
848
.local_name = "uSNCreated",
854
.local_name = "userPassword",
858
/* userAccountControl */
860
.local_name = "userAccountControl",
866
.local_name = "whenChanged",
872
.local_name = "whenCreated",
878
.local_name = "unixName",
882
.remote_name = "uidNumber",
883
.convert_local = lookup_uid,
888
/* gidNumber. Perhaps make into generate so we can distinguish between
889
* groups and accounts? */
891
.local_name = "unixName",
895
.remote_name = "gidNumber",
896
.convert_local = lookup_gid,
903
.local_name = "unixName",
907
.remote_name = "homeDirectory",
908
.convert_local = lookup_homedir,
917
/* the context init function */
918
static int samba3sam_init(struct ldb_module *module)
922
ret = ldb_map_init(module, samba3_attributes, samba3_objectclasses, NULL, NULL, "samba3sam");
923
if (ret != LDB_SUCCESS)
926
return ldb_next_init(module);
929
_PUBLIC_ const struct ldb_module_ops ldb_samba3sam_module_ops = {
932
.init_context = samba3sam_init,