NTSTATUS serverinfo_to_SamInfo6(struct auth_serversupplied_info *server_info, struct netr_SamInfo6 *sam6) { struct pdb_domain_info *dominfo; struct netr_SamInfo3 *info3; if ((pdb_capabilities() & PDB_CAP_ADS) == 0) { DEBUG(10,("Not adding validation info level 6 " "without ADS passdb backend\n")); return NT_STATUS_INVALID_INFO_CLASS; } dominfo = pdb_get_domain_info(sam6); if (dominfo == NULL) { return NT_STATUS_NO_MEMORY; } info3 = copy_netr_SamInfo3(sam6, server_info->info3); if (!info3) { return NT_STATUS_NO_MEMORY; } if (server_info->session_key.length) { memcpy(info3->base.key.key, server_info->session_key.data, MIN(sizeof(info3->base.key.key), server_info->session_key.length)); } if (server_info->lm_session_key.length) { memcpy(info3->base.LMSessKey.key, server_info->lm_session_key.data, MIN(sizeof(info3->base.LMSessKey.key), server_info->lm_session_key.length)); } sam6->base = info3->base; sam6->sidcount = 0; sam6->sids = NULL; sam6->dns_domainname.string = talloc_strdup(sam6, dominfo->dns_domain); if (sam6->dns_domainname.string == NULL) { return NT_STATUS_NO_MEMORY; } sam6->principal_name.string = talloc_asprintf( sam6, "%s@%s", sam6->base.account_name.string, sam6->dns_domainname.string); if (sam6->principal_name.string == NULL) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; }
bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid) { struct GUID *dyn_guid; fstring key; size_t size = 0; struct GUID new_guid; #if _SAMBA_BUILD_ == 4 if (strequal(domain, get_global_sam_name()) && (pdb_capabilities() & PDB_CAP_ADS)) { struct pdb_domain_info *domain_info; domain_info = pdb_get_domain_info(talloc_tos()); if (!domain_info) { /* If we have a ADS-capable passdb backend, we * must never make up our own SID, it will * already be in the directory */ DEBUG(0, ("Unable to fetch a Domain GUID from the directory!\n")); return false; } *guid = domain_info->guid; return true; } #endif slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain); strupper_m(key); dyn_guid = (struct GUID *)secrets_fetch(key, &size); if (!dyn_guid) { if (lp_server_role() == ROLE_DOMAIN_PDC) { new_guid = GUID_random(); if (!secrets_store_domain_guid(domain, &new_guid)) return False; dyn_guid = (struct GUID *)secrets_fetch(key, &size); } if (dyn_guid == NULL) { return False; } } if (size != sizeof(struct GUID)) { DEBUG(1,("UUID size %d is wrong!\n", (int)size)); SAFE_FREE(dyn_guid); return False; } *guid = *dyn_guid; SAFE_FREE(dyn_guid); return True; }
bool secrets_store_domain_guid(const char *domain, struct GUID *guid) { fstring key; #if _SAMBA_BUILD_ == 4 if (strequal(domain, get_global_sam_name()) && (pdb_capabilities() & PDB_CAP_ADS)) { /* If we have a ADS-capable passdb backend, we * must never make up our own GUID, it will * already be in the directory */ DEBUG(0, ("Refusing to store a Domain GUID, this should be read from the directory not stored here\n")); return false; } #endif slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain); strupper_m(key); return secrets_store(key, guid, sizeof(struct GUID)); }
bool secrets_store_domain_sid(const char *domain, const struct dom_sid *sid) { bool ret; #if _SAMBA_BUILD_ == 4 if (strequal(domain, get_global_sam_name()) && (pdb_capabilities() & PDB_CAP_ADS)) { /* If we have a ADS-capable passdb backend, we * must never make up our own SID, it will * already be in the directory */ DEBUG(0, ("Refusing to store a Domain SID, this should be read from the directory not stored here\n")); return false; } #endif ret = secrets_store(domain_sid_keystr(domain), sid, sizeof(struct dom_sid )); /* Force a re-query, in case we modified our domain */ if (ret) reset_global_sam_sid(); return ret; }
bool secrets_fetch_domain_sid(const char *domain, struct dom_sid *sid) { struct dom_sid *dyn_sid; size_t size = 0; #if _SAMBA_BUILD_ == 4 if (strequal(domain, get_global_sam_name()) && (pdb_capabilities() & PDB_CAP_ADS)) { struct pdb_domain_info *domain_info; domain_info = pdb_get_domain_info(talloc_tos()); if (!domain_info) { /* If we have a ADS-capable passdb backend, we * must never make up our own SID, it will * already be in the directory */ DEBUG(0, ("Unable to fetch a Domain SID from the directory!\n")); return false; } *sid = domain_info->sid; return true; } #endif dyn_sid = (struct dom_sid *)secrets_fetch(domain_sid_keystr(domain), &size); if (dyn_sid == NULL) return False; if (size != sizeof(struct dom_sid)) { SAFE_FREE(dyn_sid); return False; } *sid = *dyn_sid; SAFE_FREE(dyn_sid); return True; }
static int net_groupmap_set(struct net_context *c, int argc, const char **argv) { const char *ntgroup = NULL; struct group *grp = NULL; GROUP_MAP *map; bool have_map = false; if ((argc < 1) || (argc > 2) || c->display_usage) { d_printf("%s\n%s", _("Usage:"), _(" net groupmap set \"NT Group\" " "[\"unix group\"] [-C \"comment\"] [-L] [-D]\n")); return -1; } if ( c->opt_localgroup && c->opt_domaingroup ) { d_printf(_("Can only specify -L or -D, not both\n")); return -1; } ntgroup = argv[0]; if (argc == 2) { grp = getgrnam(argv[1]); if (grp == NULL) { d_fprintf(stderr, _("Could not find unix group %s\n"), argv[1]); return -1; } } map = talloc_zero(NULL, GROUP_MAP); if (!map) { d_printf(_("Out of memory!\n")); return -1; } have_map = pdb_getgrnam(map, ntgroup); if (!have_map) { struct dom_sid sid; have_map = ( (strncmp(ntgroup, "S-", 2) == 0) && string_to_sid(&sid, ntgroup) && pdb_getgrsid(map, sid) ); } if (!have_map) { /* Ok, add it */ if (grp == NULL) { d_fprintf(stderr, _("Could not find group mapping for %s\n"), ntgroup); TALLOC_FREE(map); return -1; } map->gid = grp->gr_gid; if (c->opt_rid == 0) { if ( pdb_capabilities() & PDB_CAP_STORE_RIDS ) { if ( !pdb_new_rid((uint32*)&c->opt_rid) ) { d_fprintf( stderr, _("Could not allocate new RID\n")); TALLOC_FREE(map); return -1; } } else { c->opt_rid = algorithmic_pdb_gid_to_group_rid(map->gid); } } sid_compose(&map->sid, get_global_sam_sid(), c->opt_rid); map->sid_name_use = SID_NAME_DOM_GRP; map->nt_name = talloc_strdup(map, ntgroup); map->comment = talloc_strdup(map, ""); if (!map->nt_name || !map->comment) { d_printf(_("Out of memory!\n")); TALLOC_FREE(map); return -1; } if (!NT_STATUS_IS_OK(pdb_add_group_mapping_entry(map))) { d_fprintf(stderr, _("Could not add mapping entry for %s\n"), ntgroup); TALLOC_FREE(map); return -1; } } /* Now we have a mapping entry, update that stuff */ if ( c->opt_localgroup || c->opt_domaingroup ) { if (map->sid_name_use == SID_NAME_WKN_GRP) { d_fprintf(stderr, _("Can't change type of the BUILTIN " "group %s\n"), map->nt_name); TALLOC_FREE(map); return -1; } } if (c->opt_localgroup) map->sid_name_use = SID_NAME_ALIAS; if (c->opt_domaingroup) map->sid_name_use = SID_NAME_DOM_GRP; /* The case (opt_domaingroup && opt_localgroup) was tested for above */ if ((c->opt_comment != NULL) && (strlen(c->opt_comment) > 0)) { map->comment = talloc_strdup(map, c->opt_comment); if (!map->comment) { d_printf(_("Out of memory!\n")); TALLOC_FREE(map); return -1; } } if ((c->opt_newntname != NULL) && (strlen(c->opt_newntname) > 0)) { map->nt_name = talloc_strdup(map, c->opt_newntname); if (!map->nt_name) { d_printf(_("Out of memory!\n")); TALLOC_FREE(map); return -1; } } if (grp != NULL) map->gid = grp->gr_gid; if (!NT_STATUS_IS_OK(pdb_update_group_mapping_entry(map))) { d_fprintf(stderr, _("Could not update group mapping for %s\n"), ntgroup); TALLOC_FREE(map); return -1; } TALLOC_FREE(map); return 0; }
static int net_groupmap_add(struct net_context *c, int argc, const char **argv) { struct dom_sid sid; fstring ntgroup = ""; fstring unixgrp = ""; fstring string_sid = ""; fstring type = ""; fstring ntcomment = ""; enum lsa_SidType sid_type = SID_NAME_DOM_GRP; uint32 rid = 0; gid_t gid; int i; GROUP_MAP *map; const char *name_type; const char add_usage_str[] = N_("net groupmap add " "{rid=<int>|sid=<string>}" " unixgroup=<string> " "[type=<domain|local|builtin>] " "[ntgroup=<string>] " "[comment=<string>]"); name_type = "domain group"; if (c->display_usage) { d_printf("%s\n%s\n", _("Usage:\n"), add_usage_str); return 0; } /* get the options */ for ( i=0; i<argc; i++ ) { if ( !strncasecmp_m(argv[i], "rid", strlen("rid")) ) { rid = get_int_param(argv[i]); if ( rid < DOMAIN_RID_ADMINS ) { d_fprintf(stderr, _("RID must be greater than %d\n"), (uint32)DOMAIN_RID_ADMINS-1); return -1; } } else if ( !strncasecmp_m(argv[i], "unixgroup", strlen("unixgroup")) ) { fstrcpy( unixgrp, get_string_param( argv[i] ) ); if ( !unixgrp[0] ) { d_fprintf(stderr,_( "must supply a name\n")); return -1; } } else if ( !strncasecmp_m(argv[i], "ntgroup", strlen("ntgroup")) ) { fstrcpy( ntgroup, get_string_param( argv[i] ) ); if ( !ntgroup[0] ) { d_fprintf(stderr, _("must supply a name\n")); return -1; } } else if ( !strncasecmp_m(argv[i], "sid", strlen("sid")) ) { fstrcpy( string_sid, get_string_param( argv[i] ) ); if ( !string_sid[0] ) { d_fprintf(stderr, _("must supply a SID\n")); return -1; } } else if ( !strncasecmp_m(argv[i], "comment", strlen("comment")) ) { fstrcpy( ntcomment, get_string_param( argv[i] ) ); if ( !ntcomment[0] ) { d_fprintf(stderr, _("must supply a comment string\n")); return -1; } } else if ( !strncasecmp_m(argv[i], "type", strlen("type")) ) { fstrcpy( type, get_string_param( argv[i] ) ); switch ( type[0] ) { case 'b': case 'B': sid_type = SID_NAME_WKN_GRP; name_type = "wellknown group"; break; case 'd': case 'D': sid_type = SID_NAME_DOM_GRP; name_type = "domain group"; break; case 'l': case 'L': sid_type = SID_NAME_ALIAS; name_type = "alias (local) group"; break; default: d_fprintf(stderr, _("unknown group type %s\n"), type); return -1; } } else { d_fprintf(stderr, _("Bad option: %s\n"), argv[i]); return -1; } } if ( !unixgrp[0] ) { d_printf("%s\n%s\n", _("Usage:\n"), add_usage_str); return -1; } if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) { d_fprintf(stderr, _("Can't lookup UNIX group %s\n"), unixgrp); return -1; } map = talloc_zero(NULL, GROUP_MAP); if (!map) { return -1; } /* Default is domain group. */ map->sid_name_use = SID_NAME_DOM_GRP; if (pdb_getgrgid(map, gid)) { d_printf(_("Unix group %s already mapped to SID %s\n"), unixgrp, sid_string_tos(&map->sid)); TALLOC_FREE(map); return -1; } TALLOC_FREE(map); if ( (rid == 0) && (string_sid[0] == '\0') ) { d_printf(_("No rid or sid specified, choosing a RID\n")); if (pdb_capabilities() & PDB_CAP_STORE_RIDS) { if (!pdb_new_rid(&rid)) { d_printf(_("Could not get new RID\n")); } } else { rid = algorithmic_pdb_gid_to_group_rid(gid); } d_printf(_("Got RID %d\n"), rid); } /* append the rid to our own domain/machine SID if we don't have a full SID */ if ( !string_sid[0] ) { sid_compose(&sid, get_global_sam_sid(), rid); sid_to_fstring(string_sid, &sid); } if (!ntcomment[0]) { switch (sid_type) { case SID_NAME_WKN_GRP: fstrcpy(ntcomment, "Wellknown Unix group"); break; case SID_NAME_DOM_GRP: fstrcpy(ntcomment, "Domain Unix group"); break; case SID_NAME_ALIAS: fstrcpy(ntcomment, "Local Unix group"); break; default: fstrcpy(ntcomment, "Unix group"); break; } } if (!ntgroup[0] ) strlcpy(ntgroup, unixgrp, sizeof(ntgroup)); if (!NT_STATUS_IS_OK(add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment))) { d_fprintf(stderr, _("adding entry for group %s failed!\n"), ntgroup); return -1; } d_printf(_("Successfully added group %s to the mapping db as a %s\n"), ntgroup, name_type); return 0; }