X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fpassdb%2Fpdb_interface.c;h=b8247f25952035e2b090ce5e37c628116a475bed;hb=8e90b93ddceabd582cb28e40882036e7772608aa;hp=a6a777436ec18e7637a74893890ee17f3deadb0e;hpb=605d7d965a33d6a4be632dde9b15abb42801fdaf;p=obnox%2Fsamba%2Fsamba-obnox.git diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index a6a777436ec..b8247f25952 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -28,10 +28,14 @@ #include "../librpc/gen_ndr/samr.h" #include "../librpc/gen_ndr/drsblobs.h" #include "../librpc/gen_ndr/ndr_drsblobs.h" -#include "memcache.h" +#include "../librpc/gen_ndr/idmap.h" +#include "../lib/util/memcache.h" #include "nsswitch/winbind_client.h" #include "../libcli/security/security.h" #include "../lib/util/util_pw.h" +#include "passdb/pdb_secrets.h" +#include "lib/util_sid_passdb.h" +#include "idmap_cache.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -116,11 +120,11 @@ const struct pdb_init_function_entry *pdb_get_backends(void) * smb_idle_event_list that used to exist in lib/module.c. -- VL */ -static struct event_context *pdb_event_ctx; +static struct tevent_context *pdb_tevent_ctx; -struct event_context *pdb_get_event_context(void) +struct tevent_context *pdb_get_tevent_context(void) { - return pdb_event_ctx; + return pdb_tevent_ctx; } /****************************************************************** @@ -193,29 +197,17 @@ static struct pdb_methods *pdb_get_methods_reload( bool reload ) static struct pdb_methods *pdb = NULL; if ( pdb && reload ) { - pdb->free_private_data( &(pdb->private_data) ); + if (pdb->free_private_data != NULL) { + pdb->free_private_data( &(pdb->private_data) ); + } if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) { - char *msg = NULL; - if (asprintf(&msg, "pdb_get_methods_reload: " - "failed to get pdb methods for backend %s\n", - lp_passdb_backend()) > 0) { - smb_panic(msg); - } else { - smb_panic("pdb_get_methods_reload"); - } + return NULL; } } if ( !pdb ) { if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) { - char *msg = NULL; - if (asprintf(&msg, "pdb_get_methods_reload: " - "failed to get pdb methods for backend %s\n", - lp_passdb_backend()) > 0) { - smb_panic(msg); - } else { - smb_panic("pdb_get_methods_reload"); - } + return NULL; } } @@ -224,7 +216,21 @@ static struct pdb_methods *pdb_get_methods_reload( bool reload ) static struct pdb_methods *pdb_get_methods(void) { - return pdb_get_methods_reload(False); + struct pdb_methods *pdb; + + pdb = pdb_get_methods_reload(false); + if (!pdb) { + char *msg = NULL; + if (asprintf(&msg, "pdb_get_methods: " + "failed to get pdb methods for backend %s\n", + lp_passdb_backend()) > 0) { + smb_panic(msg); + } else { + smb_panic("pdb_get_methods"); + } + } + + return pdb; } struct pdb_domain_info *pdb_get_domain_info(TALLOC_CTX *mem_ctx) @@ -362,7 +368,7 @@ static bool guest_user_info( struct samu *user ) { struct passwd *pwd; NTSTATUS result; - const char *guestname = lp_guestaccount(); + const char *guestname = lp_guest_account(); pwd = Get_Pwnam_alloc(talloc_tos(), guestname); if (pwd == NULL) { @@ -454,11 +460,9 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods, fstring name2; if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') { - add_script = talloc_strdup(tmp_ctx, - lp_adduser_script()); + add_script = lp_add_user_script(tmp_ctx); } else { - add_script = talloc_strdup(tmp_ctx, - lp_addmachine_script()); + add_script = lp_add_machine_script(tmp_ctx); } if (!add_script || add_script[0] == '\0') { @@ -470,7 +474,9 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods, /* lowercase the username before creating the Unix account for compatibility with previous Samba releases */ fstrcpy( name2, name ); - strlower_m( name2 ); + if (!strlower_m( name2 )) { + return NT_STATUS_INVALID_PARAMETER; + } add_script = talloc_all_string_sub(tmp_ctx, add_script, "%u", @@ -552,7 +558,7 @@ static int smb_delete_user(const char *unix_user) return -1; } - del_script = talloc_strdup(talloc_tos(), lp_deluser_script()); + del_script = lp_delete_user_script(talloc_tos()); if (!del_script || !*del_script) { return -1; } @@ -596,7 +602,9 @@ static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods, external scripts */ fstrcpy( username, pdb_get_username(sam_acct) ); - strlower_m( username ); + if (!strlower_m( username )) { + return status; + } smb_delete_user( username ); @@ -1166,29 +1174,6 @@ NTSTATUS pdb_lookup_rids(const struct dom_sid *domain_sid, return pdb->lookup_rids(pdb, domain_sid, num_rids, rids, names, attrs); } -/* - * NOTE: pdb_lookup_names is currently (2007-01-12) not used anywhere - * in the samba code. - * Unlike _lsa_lookup_sids and _samr_lookup_rids, which eventually - * also ask pdb_lookup_rids, thus looking up a bunch of rids at a time, - * the pdb_ calls _lsa_lookup_names and _samr_lookup_names come - * down to are pdb_getsampwnam and pdb_getgrnam instead of - * pdb_lookup_names. - * But in principle, it the call belongs to the API and might get - * used in this context some day. - */ -#if 0 -NTSTATUS pdb_lookup_names(const struct dom_sid *domain_sid, - int num_names, - const char **names, - uint32_t *rids, - enum lsa_SidType *attrs) -{ - struct pdb_methods *pdb = pdb_get_methods(); - return pdb->lookup_names(pdb, domain_sid, num_names, names, rids, attrs); -} -#endif - bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value) { struct pdb_methods *pdb = pdb_get_methods(); @@ -1219,23 +1204,45 @@ bool pdb_get_seq_num(time_t *seq_num) return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num)); } -bool pdb_uid_to_sid(uid_t uid, struct dom_sid *sid) +/* + * Instead of passing down a gid or uid, this function sends down a pointer + * to a unixid. + * + * This acts as an in-out variable so that the idmap functions can correctly + * receive ID_TYPE_BOTH, filling in cache details correctly rather than forcing + * the cache to store ID_TYPE_UID or ID_TYPE_GID. + */ +bool pdb_id_to_sid(struct unixid *id, struct dom_sid *sid) { struct pdb_methods *pdb = pdb_get_methods(); - return pdb->uid_to_sid(pdb, uid, sid); -} + bool ret; -bool pdb_gid_to_sid(gid_t gid, struct dom_sid *sid) -{ - struct pdb_methods *pdb = pdb_get_methods(); - return pdb->gid_to_sid(pdb, gid, sid); + ret = pdb->id_to_sid(pdb, id, sid); + + if (ret == true) { + idmap_cache_set_sid2unixid(sid, id); + } + + return ret; } -bool pdb_sid_to_id(const struct dom_sid *sid, uid_t *uid, gid_t *gid, - enum lsa_SidType *type) +bool pdb_sid_to_id(const struct dom_sid *sid, struct unixid *id) { struct pdb_methods *pdb = pdb_get_methods(); - return pdb->sid_to_id(pdb, sid, uid, gid, type); + bool ret; + + /* only ask the backend if it is responsible */ + if (!sid_check_object_is_for_passdb(sid)) { + return false; + } + + ret = pdb->sid_to_id(pdb, sid, id); + + if (ret == true) { + idmap_cache_set_sid2unixid(sid, id); + } + + return ret; } uint32_t pdb_capabilities(void) @@ -1315,13 +1322,14 @@ bool pdb_new_rid(uint32_t *rid) If uninitialised, context will auto-init on first use. ***************************************************************/ -bool initialize_password_db(bool reload, struct event_context *event_ctx) +bool initialize_password_db(bool reload, struct tevent_context *tevent_ctx) { - pdb_event_ctx = event_ctx; + if (tevent_ctx) { + pdb_tevent_ctx = tevent_ctx; + } return (pdb_get_methods_reload(reload) != NULL); } - /*************************************************************************** Default implementations of some functions. ****************************************************************************/ @@ -1386,7 +1394,7 @@ static bool pdb_default_uid_to_sid(struct pdb_methods *methods, uid_t uid, struct passwd *unix_pw; bool ret; - unix_pw = sys_getpwuid( uid ); + unix_pw = getpwuid( uid ); if ( !unix_pw ) { DEBUG(4,("pdb_default_uid_to_sid: host has no idea of uid " @@ -1438,18 +1446,54 @@ static bool pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid, return true; } +static bool pdb_default_id_to_sid(struct pdb_methods *methods, struct unixid *id, + struct dom_sid *sid) +{ + switch (id->type) { + case ID_TYPE_UID: + return pdb_default_uid_to_sid(methods, id->id, sid); + + case ID_TYPE_GID: + return pdb_default_gid_to_sid(methods, id->id, sid); + + default: + return false; + } +} +/** + * The "Unix User" and "Unix Group" domains have a special + * id mapping that is a rid-algorithm with range starting at 0. + */ +bool pdb_sid_to_id_unix_users_and_groups(const struct dom_sid *sid, + struct unixid *id) +{ + uint32_t rid; + + id->id = -1; + + if (sid_peek_check_rid(&global_sid_Unix_Users, sid, &rid)) { + id->id = rid; + id->type = ID_TYPE_UID; + return true; + } + + if (sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid)) { + id->id = rid; + id->type = ID_TYPE_GID; + return true; + } + + return false; +} + static bool pdb_default_sid_to_id(struct pdb_methods *methods, const struct dom_sid *sid, - uid_t *uid, gid_t *gid, - enum lsa_SidType *type) + struct unixid *id) { TALLOC_CTX *mem_ctx; bool ret = False; - const char *name; uint32_t rid; - - *uid = -1; - *gid = -1; + id->id = -1; mem_ctx = talloc_new(NULL); @@ -1459,27 +1503,45 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, } if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + const char *name; + enum lsa_SidType type; + uid_t uid; + gid_t gid; /* Here we might have users as well as groups and aliases */ - ret = lookup_global_sam_rid(mem_ctx, rid, &name, type, uid, gid); + ret = lookup_global_sam_rid(mem_ctx, rid, &name, &type, &uid, &gid); + if (ret) { + switch (type) { + case SID_NAME_DOM_GRP: + case SID_NAME_ALIAS: + id->type = ID_TYPE_GID; + id->id = gid; + break; + case SID_NAME_USER: + id->type = ID_TYPE_UID; + id->id = uid; + break; + default: + DEBUG(5, ("SID %s belongs to our domain, and " + "an object exists in the database, " + "but it is neither a user nor a " + "group (got type %d).\n", + sid_string_dbg(sid), type)); + ret = false; + } + } else { + DEBUG(5, ("SID %s belongs to our domain, but there is " + "no corresponding object in the database.\n", + sid_string_dbg(sid))); + } goto done; } - /* check for "Unix User" */ - - if ( sid_peek_check_rid(&global_sid_Unix_Users, sid, &rid) ) { - *uid = rid; - *type = SID_NAME_USER; - ret = True; - goto done; - } - - /* check for "Unix Group" */ - - if ( sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid) ) { - *gid = rid; - *type = SID_NAME_ALIAS; - ret = True; - goto done; + /* + * "Unix User" and "Unix Group" + */ + ret = pdb_sid_to_id_unix_users_and_groups(sid, id); + if (ret == true) { + goto done; } /* BUILTIN */ @@ -1508,8 +1570,8 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, goto done; } - *gid = map->gid; - *type = SID_NAME_ALIAS; + id->id = map->gid; + id->type = ID_TYPE_GID; ret = True; goto done; } @@ -1607,7 +1669,7 @@ static NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods, uid_to_sid(&sid, uids[i]); - if (!sid_check_is_in_our_domain(&sid)) { + if (!sid_check_is_in_our_sam(&sid)) { DEBUG(5, ("Inconsistent SAM -- group member uid not " "in our domain\n")); continue; @@ -1805,7 +1867,7 @@ static NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods, } /* Should not happen, but better check once too many */ - if (!sid_check_is_domain(domain_sid)) { + if (!sid_check_is_our_sam(domain_sid)) { return NT_STATUS_INVALID_HANDLE; } @@ -1836,65 +1898,6 @@ static NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods, return result; } -#if 0 -static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods, - const struct dom_sid *domain_sid, - int num_names, - const char **names, - uint32_t *rids, - enum lsa_SidType *attrs) -{ - int i; - NTSTATUS result; - bool have_mapped = False; - bool have_unmapped = False; - - if (sid_check_is_builtin(domain_sid)) { - - for (i=0; i %d:%d\n", names[i], - rids[i], attrs[i])); - have_mapped = True; - } else { - have_unmapped = True; - attrs[i] = SID_NAME_UNKNOWN; - } - } - - done: - - result = NT_STATUS_NONE_MAPPED; - - if (have_mapped) - result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK; - - return result; -} -#endif - static int pdb_search_destructor(struct pdb_search *search) { if ((!search->search_ended) && (search->search_end != NULL)) { @@ -2142,6 +2145,13 @@ bool pdb_get_trusteddom_pw(const char *domain, char** pwd, struct dom_sid *sid, pass_last_set_time); } +NTSTATUS pdb_get_trusteddom_creds(const char *domain, TALLOC_CTX *mem_ctx, + struct cli_credentials **creds) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->get_trusteddom_creds(pdb, domain, mem_ctx, creds); +} + bool pdb_set_trusteddom_pw(const char* domain, const char* pwd, const struct dom_sid *sid) { @@ -2179,6 +2189,15 @@ static bool pdb_default_get_trusteddom_pw(struct pdb_methods *methods, } +static NTSTATUS pdb_default_get_trusteddom_creds(struct pdb_methods *methods, + const char *domain, + TALLOC_CTX *mem_ctx, + struct cli_credentials **creds) +{ + *creds = NULL; + return NT_STATUS_NOT_IMPLEMENTED; +} + static bool pdb_default_set_trusteddom_pw(struct pdb_methods *methods, const char* domain, const char* pwd, @@ -2380,6 +2399,114 @@ static struct pdb_domain_info *pdb_default_get_domain_info( return NULL; } +/***************************************************************** + UPN suffixes + *****************************************************************/ +static NTSTATUS pdb_default_enum_upn_suffixes(struct pdb_methods *pdb, + TALLOC_CTX *mem_ctx, + uint32_t *num_suffixes, + char ***suffixes) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_default_set_upn_suffixes(struct pdb_methods *pdb, + uint32_t num_suffixes, + const char **suffixes) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS pdb_enum_upn_suffixes(TALLOC_CTX *mem_ctx, + uint32_t *num_suffixes, + char ***suffixes) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->enum_upn_suffixes(pdb, mem_ctx, num_suffixes, suffixes); +} + +NTSTATUS pdb_set_upn_suffixes(uint32_t num_suffixes, + const char **suffixes) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->set_upn_suffixes(pdb, num_suffixes, suffixes); +} + +/******************************************************************* + idmap control methods + *******************************************************************/ +static bool pdb_default_is_responsible_for_our_sam( + struct pdb_methods *methods) +{ + return true; +} + +static bool pdb_default_is_responsible_for_builtin( + struct pdb_methods *methods) +{ + return true; +} + +static bool pdb_default_is_responsible_for_wellknown( + struct pdb_methods *methods) +{ + return false; +} + +static bool pdb_default_is_responsible_for_unix_users( + struct pdb_methods *methods) +{ + return true; +} + +static bool pdb_default_is_responsible_for_unix_groups( + struct pdb_methods *methods) +{ + return true; +} + +static bool pdb_default_is_responsible_for_everything_else( + struct pdb_methods *methods) +{ + return false; +} + +bool pdb_is_responsible_for_our_sam(void) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->is_responsible_for_our_sam(pdb); +} + +bool pdb_is_responsible_for_builtin(void) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->is_responsible_for_builtin(pdb); +} + +bool pdb_is_responsible_for_wellknown(void) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->is_responsible_for_wellknown(pdb); +} + +bool pdb_is_responsible_for_unix_users(void) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->is_responsible_for_unix_users(pdb); +} + +bool pdb_is_responsible_for_unix_groups(void) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->is_responsible_for_unix_groups(pdb); +} + +bool pdb_is_responsible_for_everything_else(void) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->is_responsible_for_everything_else(pdb); +} + /******************************************************************* secret methods *******************************************************************/ @@ -2505,14 +2632,14 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods ) (*methods)->get_account_policy = pdb_default_get_account_policy; (*methods)->set_account_policy = pdb_default_set_account_policy; (*methods)->get_seq_num = pdb_default_get_seq_num; - (*methods)->uid_to_sid = pdb_default_uid_to_sid; - (*methods)->gid_to_sid = pdb_default_gid_to_sid; + (*methods)->id_to_sid = pdb_default_id_to_sid; (*methods)->sid_to_id = pdb_default_sid_to_id; (*methods)->search_groups = pdb_default_search_groups; (*methods)->search_aliases = pdb_default_search_aliases; (*methods)->get_trusteddom_pw = pdb_default_get_trusteddom_pw; + (*methods)->get_trusteddom_creds = pdb_default_get_trusteddom_creds; (*methods)->set_trusteddom_pw = pdb_default_set_trusteddom_pw; (*methods)->del_trusteddom_pw = pdb_default_del_trusteddom_pw; (*methods)->enum_trusteddoms = pdb_default_enum_trusteddoms; @@ -2527,5 +2654,21 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods ) (*methods)->set_secret = pdb_default_set_secret; (*methods)->delete_secret = pdb_default_delete_secret; + (*methods)->enum_upn_suffixes = pdb_default_enum_upn_suffixes; + (*methods)->set_upn_suffixes = pdb_default_set_upn_suffixes; + + (*methods)->is_responsible_for_our_sam = + pdb_default_is_responsible_for_our_sam; + (*methods)->is_responsible_for_builtin = + pdb_default_is_responsible_for_builtin; + (*methods)->is_responsible_for_wellknown = + pdb_default_is_responsible_for_wellknown; + (*methods)->is_responsible_for_unix_users = + pdb_default_is_responsible_for_unix_users; + (*methods)->is_responsible_for_unix_groups = + pdb_default_is_responsible_for_unix_groups; + (*methods)->is_responsible_for_everything_else = + pdb_default_is_responsible_for_everything_else; + return NT_STATUS_OK; }