2 Unix SMB/CIFS implementation.
4 Password and authentication handling by wbclient
6 Copyright (C) Andrew Bartlett 2002
7 Copyright (C) Jelmer Vernooij 2002
8 Copyright (C) Simo Sorce 2003
9 Copyright (C) Volker Lendecke 2006
10 Copyright (C) Dan Sledz 2009
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 /* This passdb module retrieves full passdb information for local users and
27 * groups from a wbclient compatible daemon.
29 * The purpose of this module is to defer all SAM authorization information
30 * storage and retrieval to a wbc compatible daemon.
32 * This passdb backend is most useful when used in conjunction with auth_wbc.
34 * A few current limitations of this module are:
35 * - read only interface
41 #include "lib/winbind_util.h"
42 #include "passdb/pdb_wbc_sam.h"
45 /***************************************************************************
46 Default implementations of some functions.
47 ****************************************************************************/
48 static NTSTATUS
_pdb_wbc_sam_getsampw(struct pdb_methods
*methods
,
50 const struct passwd
*pwd
)
52 NTSTATUS result
= NT_STATUS_OK
;
55 return NT_STATUS_NO_SUCH_USER
;
59 /* Can we really get away with this little of information */
60 user
->methods
= methods
;
61 result
= samu_set_unix(user
, pwd
);
66 static NTSTATUS
pdb_wbc_sam_getsampwnam(struct pdb_methods
*methods
, struct samu
*user
, const char *sname
)
68 return _pdb_wbc_sam_getsampw(methods
, user
, winbind_getpwnam(sname
));
71 static NTSTATUS
pdb_wbc_sam_getsampwsid(struct pdb_methods
*methods
, struct samu
*user
, const struct dom_sid
*sid
)
73 return _pdb_wbc_sam_getsampw(methods
, user
, winbind_getpwsid(sid
));
76 static bool pdb_wbc_sam_id_to_sid(struct pdb_methods
*methods
, struct unixid
*id
,
81 return winbind_uid_to_sid(sid
, id
->id
);
84 return winbind_gid_to_sid(sid
, id
->id
);
91 static NTSTATUS
pdb_wbc_sam_enum_group_members(struct pdb_methods
*methods
,
93 const struct dom_sid
*group
,
94 uint32_t **pp_member_rids
,
95 size_t *p_num_members
)
97 return NT_STATUS_NOT_IMPLEMENTED
;
100 static NTSTATUS
pdb_wbc_sam_enum_group_memberships(struct pdb_methods
*methods
,
103 struct dom_sid
**pp_sids
,
105 uint32_t *p_num_groups
)
108 const char *username
= pdb_get_username(user
);
111 if (!winbind_get_groups(mem_ctx
, username
, &num_groups
, pp_gids
)) {
112 return NT_STATUS_NO_SUCH_USER
;
114 *p_num_groups
= num_groups
;
116 if (*p_num_groups
== 0) {
117 smb_panic("primary group missing");
120 *pp_sids
= talloc_array(mem_ctx
, struct dom_sid
, *p_num_groups
);
122 if (*pp_sids
== NULL
) {
123 TALLOC_FREE(*pp_gids
);
124 return NT_STATUS_NO_MEMORY
;
127 for (i
=0; i
< *p_num_groups
; i
++) {
128 gid_to_sid(&(*pp_sids
)[i
], (*pp_gids
)[i
]);
134 static NTSTATUS
pdb_wbc_sam_lookup_rids(struct pdb_methods
*methods
,
135 const struct dom_sid
*domain_sid
,
139 enum lsa_SidType
*attrs
)
141 NTSTATUS result
= NT_STATUS_OK
;
142 const char *p
= NULL
;
143 const char **pp
= NULL
;
145 char **account_names
= NULL
;
146 enum lsa_SidType
*attr_list
= NULL
;
149 if (!winbind_lookup_rids(talloc_tos(), domain_sid
, num_rids
, rids
,
150 &p
, &pp
, &attr_list
))
152 result
= NT_STATUS_NONE_MAPPED
;
155 domain
= discard_const_p(char, p
);
156 account_names
= discard_const_p(char *, pp
);
158 memcpy(attrs
, attr_list
, num_rids
* sizeof(enum lsa_SidType
));
160 for (i
=0; i
<num_rids
; i
++) {
161 if (attrs
[i
] == SID_NAME_UNKNOWN
) {
164 names
[i
] = talloc_strdup(names
, account_names
[i
]);
165 if (names
[i
] == NULL
) {
166 result
= NT_STATUS_NO_MEMORY
;
174 TALLOC_FREE(account_names
);
176 TALLOC_FREE(attr_list
);
180 static NTSTATUS
pdb_wbc_sam_get_account_policy(struct pdb_methods
*methods
, enum pdb_policy_type type
, uint32_t *value
)
182 return NT_STATUS_UNSUCCESSFUL
;
185 static NTSTATUS
pdb_wbc_sam_set_account_policy(struct pdb_methods
*methods
, enum pdb_policy_type type
, uint32_t value
)
187 return NT_STATUS_UNSUCCESSFUL
;
190 static bool pdb_wbc_sam_search_groups(struct pdb_methods
*methods
,
191 struct pdb_search
*search
)
196 static bool pdb_wbc_sam_search_aliases(struct pdb_methods
*methods
,
197 struct pdb_search
*search
,
198 const struct dom_sid
*sid
)
204 static bool pdb_wbc_sam_get_trusteddom_pw(struct pdb_methods
*methods
,
208 time_t *pass_last_set_time
)
214 static bool pdb_wbc_sam_set_trusteddom_pw(struct pdb_methods
*methods
,
217 const struct dom_sid
*sid
)
222 static bool pdb_wbc_sam_del_trusteddom_pw(struct pdb_methods
*methods
,
228 static NTSTATUS
pdb_wbc_sam_enum_trusteddoms(struct pdb_methods
*methods
,
230 uint32_t *num_domains
,
231 struct trustdom_info
***domains
)
233 return NT_STATUS_NOT_IMPLEMENTED
;
236 static bool _make_group_map(struct pdb_methods
*methods
, const char *domain
, const char *name
, enum lsa_SidType name_type
, gid_t gid
, struct dom_sid
*sid
, GROUP_MAP
*map
)
238 map
->nt_name
= talloc_asprintf(map
, "%s%c%s",
239 domain
, *lp_winbind_separator(), name
);
243 map
->sid_name_use
= name_type
;
249 static NTSTATUS
pdb_wbc_sam_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
252 NTSTATUS result
= NT_STATUS_OK
;
253 const char *p1
= NULL
, *p2
= NULL
;
256 enum lsa_SidType name_type
;
259 if (!winbind_lookup_sid(talloc_tos(), &sid
, &p1
, &p2
, &name_type
)) {
260 result
= NT_STATUS_NO_SUCH_GROUP
;
263 domain
= discard_const_p(char, p1
);
264 name
= discard_const_p(char, p2
);
266 if ((name_type
!= SID_NAME_DOM_GRP
) &&
267 (name_type
!= SID_NAME_DOMAIN
) &&
268 (name_type
!= SID_NAME_ALIAS
) &&
269 (name_type
!= SID_NAME_WKN_GRP
)) {
270 result
= NT_STATUS_NO_SUCH_GROUP
;
274 if (!winbind_sid_to_gid(&gid
, &sid
)) {
275 result
= NT_STATUS_NO_SUCH_GROUP
;
279 if (!_make_group_map(methods
, domain
, name
, name_type
, gid
, &sid
, map
)) {
280 result
= NT_STATUS_NO_SUCH_GROUP
;
290 static NTSTATUS
pdb_wbc_sam_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
293 NTSTATUS result
= NT_STATUS_OK
;
294 const char *p1
= NULL
, *p2
= NULL
;
298 enum lsa_SidType name_type
;
300 if (!winbind_gid_to_sid(&sid
, gid
)) {
301 result
= NT_STATUS_NO_SUCH_GROUP
;
305 if (!winbind_lookup_sid(talloc_tos(), &sid
, &p1
, &p2
, &name_type
)) {
306 result
= NT_STATUS_NO_SUCH_GROUP
;
309 domain
= discard_const_p(char, p1
);
310 name
= discard_const_p(char, p2
);
312 if ((name_type
!= SID_NAME_DOM_GRP
) &&
313 (name_type
!= SID_NAME_DOMAIN
) &&
314 (name_type
!= SID_NAME_ALIAS
) &&
315 (name_type
!= SID_NAME_WKN_GRP
)) {
316 result
= NT_STATUS_NO_SUCH_GROUP
;
320 if (!_make_group_map(methods
, domain
, name
, name_type
, gid
, &sid
, map
)) {
321 result
= NT_STATUS_NO_SUCH_GROUP
;
332 static NTSTATUS
pdb_wbc_sam_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
335 NTSTATUS result
= NT_STATUS_OK
;
336 const char *domain
= "";
339 enum lsa_SidType name_type
;
341 if (!winbind_lookup_name(domain
, name
, &sid
, &name_type
)) {
342 result
= NT_STATUS_NO_SUCH_GROUP
;
346 if ((name_type
!= SID_NAME_DOM_GRP
) &&
347 (name_type
!= SID_NAME_DOMAIN
) &&
348 (name_type
!= SID_NAME_ALIAS
) &&
349 (name_type
!= SID_NAME_WKN_GRP
)) {
350 result
= NT_STATUS_NO_SUCH_GROUP
;
354 if (!winbind_sid_to_gid(&gid
, &sid
)) {
355 result
= NT_STATUS_NO_SUCH_GROUP
;
359 if (!_make_group_map(methods
, domain
, name
, name_type
, gid
, &sid
, map
)) {
360 result
= NT_STATUS_NO_SUCH_GROUP
;
369 static NTSTATUS
pdb_wbc_sam_enum_group_mapping(struct pdb_methods
*methods
,
370 const struct dom_sid
*sid
, enum lsa_SidType sid_name_use
,
371 GROUP_MAP
***pp_rmap
, size_t *p_num_entries
,
374 return NT_STATUS_NOT_IMPLEMENTED
;
377 static NTSTATUS
pdb_wbc_sam_get_aliasinfo(struct pdb_methods
*methods
,
378 const struct dom_sid
*sid
,
379 struct acct_info
*info
)
381 return NT_STATUS_NOT_IMPLEMENTED
;
384 static NTSTATUS
pdb_wbc_sam_enum_aliasmem(struct pdb_methods
*methods
,
385 const struct dom_sid
*alias
,
387 struct dom_sid
**pp_members
,
388 size_t *p_num_members
)
390 return NT_STATUS_NOT_IMPLEMENTED
;
393 static NTSTATUS
pdb_wbc_sam_alias_memberships(struct pdb_methods
*methods
,
395 const struct dom_sid
*domain_sid
,
396 const struct dom_sid
*members
,
398 uint32_t **pp_alias_rids
,
399 size_t *p_num_alias_rids
)
401 if (!winbind_get_sid_aliases(mem_ctx
, domain_sid
,
402 members
, num_members
, pp_alias_rids
, p_num_alias_rids
))
403 return NT_STATUS_UNSUCCESSFUL
;
408 static NTSTATUS
pdb_init_wbc_sam(struct pdb_methods
**pdb_method
, const char *location
)
412 if (!NT_STATUS_IS_OK(result
= make_pdb_method( pdb_method
))) {
416 (*pdb_method
)->name
= "wbc_sam";
418 (*pdb_method
)->getsampwnam
= pdb_wbc_sam_getsampwnam
;
419 (*pdb_method
)->getsampwsid
= pdb_wbc_sam_getsampwsid
;
421 (*pdb_method
)->getgrsid
= pdb_wbc_sam_getgrsid
;
422 (*pdb_method
)->getgrgid
= pdb_wbc_sam_getgrgid
;
423 (*pdb_method
)->getgrnam
= pdb_wbc_sam_getgrnam
;
424 (*pdb_method
)->enum_group_mapping
= pdb_wbc_sam_enum_group_mapping
;
425 (*pdb_method
)->enum_group_members
= pdb_wbc_sam_enum_group_members
;
426 (*pdb_method
)->enum_group_memberships
= pdb_wbc_sam_enum_group_memberships
;
427 (*pdb_method
)->get_aliasinfo
= pdb_wbc_sam_get_aliasinfo
;
428 (*pdb_method
)->enum_aliasmem
= pdb_wbc_sam_enum_aliasmem
;
429 (*pdb_method
)->enum_alias_memberships
= pdb_wbc_sam_alias_memberships
;
430 (*pdb_method
)->lookup_rids
= pdb_wbc_sam_lookup_rids
;
431 (*pdb_method
)->get_account_policy
= pdb_wbc_sam_get_account_policy
;
432 (*pdb_method
)->set_account_policy
= pdb_wbc_sam_set_account_policy
;
433 (*pdb_method
)->id_to_sid
= pdb_wbc_sam_id_to_sid
;
435 (*pdb_method
)->search_groups
= pdb_wbc_sam_search_groups
;
436 (*pdb_method
)->search_aliases
= pdb_wbc_sam_search_aliases
;
438 (*pdb_method
)->get_trusteddom_pw
= pdb_wbc_sam_get_trusteddom_pw
;
439 (*pdb_method
)->set_trusteddom_pw
= pdb_wbc_sam_set_trusteddom_pw
;
440 (*pdb_method
)->del_trusteddom_pw
= pdb_wbc_sam_del_trusteddom_pw
;
441 (*pdb_method
)->enum_trusteddoms
= pdb_wbc_sam_enum_trusteddoms
;
443 (*pdb_method
)->private_data
= NULL
;
444 (*pdb_method
)->free_private_data
= NULL
;
449 NTSTATUS
pdb_wbc_sam_init(void)
451 return smb_register_passdb(PASSDB_INTERFACE_VERSION
, "wbc_sam", pdb_init_wbc_sam
);