/********************************************************* Figure out if the input was an NT group or a SID string. Return the SID. **********************************************************/ static bool get_sid_from_input(struct dom_sid *sid, char *input) { GROUP_MAP *map; map = talloc_zero(NULL, GROUP_MAP); if (!map) { return false; } if (strncasecmp_m( input, "S-", 2)) { /* Perhaps its the NT group name? */ if (!pdb_getgrnam(map, input)) { printf(_("NT Group %s doesn't exist in mapping DB\n"), input); TALLOC_FREE(map); return false; } else { *sid = map->sid; } } else { if (!string_to_sid(sid, input)) { printf(_("converting sid %s from a string failed!\n"), input); TALLOC_FREE(map); return false; } } TALLOC_FREE(map); return true; }
static bool test_strncasecmp_m(struct torture_context *tctx) { /* file.{accented e} in iso8859-1 */ const char file_iso8859_1[7] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xe9, 0 }; /* file.{accented e} in utf8 */ const char file_utf8[8] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xc3, 0xa9, 0 }; torture_assert(tctx, strncasecmp_m("foo", "bar", 3) != 0, "different strings"); torture_assert(tctx, strncasecmp_m("foo", "foo", 3) == 0, "same case strings"); torture_assert(tctx, strncasecmp_m("foo", "Foo", 3) == 0, "different case strings"); torture_assert(tctx, strncasecmp_m("fool", "Foo", 3) == 0, "different case strings"); torture_assert(tctx, strncasecmp_m("fool", "Fool", 40) == 0, "over size"); torture_assert(tctx, strncasecmp_m("BLA", "Fool", 0) == 0, "empty"); torture_assert(tctx, strncasecmp_m(NULL, "Foo", 3) != 0, "one NULL"); torture_assert(tctx, strncasecmp_m("foo", NULL, 3) != 0, "other NULL"); torture_assert(tctx, strncasecmp_m(NULL, NULL, 3) == 0, "both NULL"); torture_assert(tctx, strncasecmp_m(file_iso8859_1, file_utf8, 6) != 0, "file.{accented e} should differ"); return true; }
/* see if two DNS names are the same */ static bool dns_name_equal(const char *name1, const char *name2) { size_t len1 = strlen(name1); size_t len2 = strlen(name2); if (name1[len1-1] == '.') len1--; if (name2[len2-1] == '.') len2--; if (len1 != len2) { return false; } return strncasecmp_m(name1, name2, len1) == 0; }
static NTSTATUS walk_xattr_streams(vfs_handle_struct *handle, files_struct *fsp, const struct smb_filename *smb_fname, bool (*fn)(struct ea_struct *ea, void *private_data), void *private_data) { NTSTATUS status; char **names; size_t i, num_names; struct streams_xattr_config *config; SMB_VFS_HANDLE_GET_DATA(handle, config, struct streams_xattr_config, return NT_STATUS_UNSUCCESSFUL); status = get_ea_names_from_file(talloc_tos(), handle->conn, fsp, smb_fname, &names, &num_names); if (!NT_STATUS_IS_OK(status)) { return status; } for (i=0; i<num_names; i++) { struct ea_struct ea; /* * We want to check with samba_private_attr_name() * whether the xattr name is a private one, * unfortunately it flags xattrs that begin with the * default streams prefix as private. * * By only calling samba_private_attr_name() in case * the xattr does NOT begin with the default prefix, * we know that if it returns 'true' it definitely one * of our internal xattr like "user.DOSATTRIB". */ if (strncasecmp_m(names[i], SAMBA_XATTR_DOSSTREAM_PREFIX, strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) != 0) { if (samba_private_attr_name(names[i])) { continue; } } if (strncmp(names[i], config->prefix, config->prefix_len) != 0) { continue; } status = get_ea_value(names, handle->conn, NULL, smb_fname, names[i], &ea); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Could not get ea %s for file %s: %s\n", names[i], smb_fname->base_name, nt_errstr(status))); continue; } ea.name = talloc_asprintf( ea.value.data, ":%s%s", names[i] + config->prefix_len, config->store_stream_type ? "" : ":$DATA"); if (ea.name == NULL) { DEBUG(0, ("talloc failed\n")); continue; } if (!fn(&ea, private_data)) { TALLOC_FREE(ea.value.data); return NT_STATUS_OK; } TALLOC_FREE(ea.value.data); } TALLOC_FREE(names); return NT_STATUS_OK; }
/********************************************************* List the groups. **********************************************************/ static int net_groupmap_list(struct net_context *c, int argc, const char **argv) { size_t entries; bool long_list = false; size_t i; fstring ntgroup = ""; fstring sid_string = ""; const char list_usage_str[] = N_("net groupmap list [verbose] " "[ntgroup=NT group] [sid=SID]\n" " verbose\tPrint verbose list\n" " ntgroup\tNT group to list\n" " sid\tSID of group to list"); if (c->display_usage) { d_printf("%s\n%s\n", _("Usage: "), list_usage_str); return 0; } if (c->opt_verbose || c->opt_long_list_entries) long_list = true; /* get the options */ for ( i=0; i<argc; i++ ) { if ( !strcasecmp_m(argv[i], "verbose")) { long_list = true; } 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( sid_string, get_string_param( argv[i] ) ); if ( !sid_string[0] ) { d_fprintf(stderr, _("must supply a SID\n")); return -1; } } else { d_fprintf(stderr, _("Bad option: %s\n"), argv[i]); d_printf("%s\n%s\n", _("Usage:"), list_usage_str); return -1; } } /* list a single group is given a name */ if ( ntgroup[0] || sid_string[0] ) { struct dom_sid sid; GROUP_MAP *map; if ( sid_string[0] ) strlcpy(ntgroup, sid_string, sizeof(ntgroup)); if (!get_sid_from_input(&sid, ntgroup)) { return -1; } map = talloc_zero(NULL, GROUP_MAP); if (!map) { return -1; } /* Get the current mapping from the database */ if(!pdb_getgrsid(map, sid)) { d_fprintf(stderr, _("Failure to local group SID in the " "database\n")); TALLOC_FREE(map); return -1; } print_map_entry(map, long_list ); TALLOC_FREE(map); } else { GROUP_MAP **maps = NULL; bool ok = false; /* enumerate all group mappings */ ok = pdb_enum_group_mapping(NULL, SID_NAME_UNKNOWN, &maps, &entries, ENUM_ALL_MAPPED); if (!ok) { return -1; } for (i=0; i<entries; i++) { print_map_entry(maps[i], long_list); } TALLOC_FREE(maps); } return 0; }
static int net_groupmap_delete(struct net_context *c, int argc, const char **argv) { struct dom_sid sid; fstring ntgroup = ""; fstring sid_string = ""; int i; const char delete_usage_str[] = N_("net groupmap delete " "{ntgroup=<string>|sid=<SID>}"); if (c->display_usage) { d_printf("%s\n%s\n", _("Usage:\n"), delete_usage_str); return 0; } /* get the options */ for ( i=0; i<argc; i++ ) { 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( sid_string, get_string_param( argv[i] ) ); if ( !sid_string[0] ) { d_fprintf(stderr, _("must supply a SID\n")); return -1; } } else { d_fprintf(stderr, _("Bad option: %s\n"), argv[i]); return -1; } } if ( !ntgroup[0] && !sid_string[0]) { d_printf("%s\n%s\n", _("Usage:\n"), delete_usage_str); return -1; } /* give preference to the SID if we have that */ if ( sid_string[0] ) strlcpy(ntgroup, sid_string, sizeof(ntgroup)); if ( !get_sid_from_input(&sid, ntgroup) ) { d_fprintf(stderr, _("Unable to resolve group %s to a SID\n"), ntgroup); return -1; } if ( !NT_STATUS_IS_OK(pdb_delete_group_mapping_entry(sid)) ) { d_fprintf(stderr, _("Failed to remove group %s from the mapping db!\n"), ntgroup); return -1; } d_printf(_("Sucessfully removed %s from the mapping db\n"), ntgroup); return 0; }
static int net_groupmap_modify(struct net_context *c, int argc, const char **argv) { struct dom_sid sid; GROUP_MAP *map = NULL; fstring ntcomment = ""; fstring type = ""; fstring ntgroup = ""; fstring unixgrp = ""; fstring sid_string = ""; enum lsa_SidType sid_type = SID_NAME_UNKNOWN; int i; gid_t gid; const char modify_usage_str[] = N_("net groupmap modify " "{ntgroup=<string>|sid=<SID>} " "[comment=<string>] " "[unixgroup=<string>] " "[type=<domain|local>]"); if (c->display_usage) { d_printf("%s\n%s\n", _("Usage:\n"), modify_usage_str); return 0; } /* get the options */ for ( i=0; i<argc; i++ ) { 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( sid_string, get_string_param( argv[i] ) ); if ( !sid_string[0] ) { d_fprintf(stderr, _("must supply a name\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], "unixgroup", strlen("unixgroup")) ) { fstrcpy( unixgrp, get_string_param( argv[i] ) ); if ( !unixgrp[0] ) { d_fprintf(stderr, _("must supply a group name\n")); return -1; } } else if ( !strncasecmp_m(argv[i], "type", strlen("type")) ) { fstrcpy( type, get_string_param( argv[i] ) ); switch ( type[0] ) { case 'd': case 'D': sid_type = SID_NAME_DOM_GRP; break; case 'l': case 'L': sid_type = SID_NAME_ALIAS; break; } } else { d_fprintf(stderr, _("Bad option: %s\n"), argv[i]); return -1; } } if ( !ntgroup[0] && !sid_string[0] ) { d_printf("%s\n%s\n", _("Usage:\n"), modify_usage_str); return -1; } /* give preference to the SID; if both the ntgroup name and SID are defined, use the SID and assume that the group name could be a new name */ if ( sid_string[0] ) { if (!get_sid_from_input(&sid, sid_string)) { return -1; } } else { if (!get_sid_from_input(&sid, ntgroup)) { return -1; } } map = talloc_zero(NULL, GROUP_MAP); if (!map) { return -1; } /* Get the current mapping from the database */ if(!pdb_getgrsid(map, sid)) { d_fprintf(stderr, _("Failed to find local group SID in the database\n")); TALLOC_FREE(map); return -1; } /* * Allow changing of group type only between domain and local * We disallow changing Builtin groups !!! (SID problem) */ if (sid_type == SID_NAME_UNKNOWN) { d_fprintf(stderr, _("Can't map to an unknown group type.\n")); TALLOC_FREE(map); return -1; } if (map->sid_name_use == SID_NAME_WKN_GRP) { d_fprintf(stderr, _("You can only change between domain and local " "groups.\n")); TALLOC_FREE(map); return -1; } map->sid_name_use = sid_type; /* Change comment if new one */ if (ntcomment[0]) { map->comment = talloc_strdup(map, ntcomment); if (!map->comment) { d_fprintf(stderr, _("Out of memory!\n")); return -1; } } if (ntgroup[0]) { map->nt_name = talloc_strdup(map, ntgroup); if (!map->nt_name) { d_fprintf(stderr, _("Out of memory!\n")); return -1; } } if ( unixgrp[0] ) { gid = nametogid( unixgrp ); if ( gid == -1 ) { d_fprintf(stderr, _("Unable to lookup UNIX group %s. " "Make sure the group exists.\n"), unixgrp); TALLOC_FREE(map); return -1; } map->gid = gid; } if (!NT_STATUS_IS_OK(pdb_update_group_mapping_entry(map))) { d_fprintf(stderr, _("Could not update group database\n")); TALLOC_FREE(map); return -1; } d_printf(_("Updated mapping entry for %s\n"), map->nt_name); 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; }