/********************************************************* Figure out if the input was an NT group or a SID string. Return the SID. **********************************************************/ static bool get_sid_from_input(DOM_SID *sid, char *input) { GROUP_MAP map; if (StrnCaseCmp( 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); return false; } else { *sid = map.sid; } } else { if (!string_to_sid(sid, input)) { printf(_("converting sid %s from a string failed!\n"), input); return false; } } return true; }
static bool dbrec2map(const struct db_record *rec, GROUP_MAP *map) { TDB_DATA key = dbwrap_record_get_key(rec); TDB_DATA value = dbwrap_record_get_value(rec); int ret = 0; fstring nt_name; fstring comment; if ((key.dsize < strlen(GROUP_PREFIX)) || (strncmp((char *)key.dptr, GROUP_PREFIX, GROUP_PREFIX_LEN) != 0)) { return False; } if (!string_to_sid(&map->sid, (const char *)key.dptr + GROUP_PREFIX_LEN)) { return False; } ret = tdb_unpack(value.dptr, value.dsize, "ddff", &map->gid, &map->sid_name_use, &nt_name, &comment); if (ret == -1) { DEBUG(3, ("dbrec2map: tdb_unpack failure\n")); return false; } map->nt_name = talloc_strdup(map, nt_name); if (!map->nt_name) { return false; } map->comment = talloc_strdup(map, comment); if (!map->comment) { return false; } return true; }
bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag) { DOM_SID new_sid; if (!u_sid) return False; DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n", u_sid)); if (!string_to_sid(&new_sid, u_sid)) { DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid)); return False; } if (!pdb_set_user_sid(sampass, &new_sid, flag)) { DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid)); return False; } return True; }
bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, DOM_SID **sids, size_t *num_sids) { const char *p, *q; p = sidstr; if (p == NULL) return False; while (p[0] != '\0') { fstring tmp; size_t sidlen; DOM_SID sid; q = strchr(p, '\n'); if (q == NULL) { DEBUG(0, ("Got invalid sidstr: %s\n", p)); return False; } sidlen = PTR_DIFF(q, p); if (sidlen >= sizeof(tmp)-1) { return false; } memcpy(tmp, p, sidlen); tmp[sidlen] = '\0'; q += 1; if (!string_to_sid(&sid, tmp)) { DEBUG(0, ("Could not parse sid %s\n", p)); return False; } if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids, num_sids))) { return False; } p = q; } return True; }
static NTSTATUS one_alias_membership(const DOM_SID *member, DOM_SID **sids, size_t *num) { fstring tmp; fstring key; char *string_sid; TDB_DATA dbuf; const char *p; NTSTATUS status = NT_STATUS_OK; TALLOC_CTX *frame = talloc_stackframe(); slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, sid_to_fstring(tmp, member)); dbuf = dbwrap_fetch_bystring(db, frame, key); if (dbuf.dptr == NULL) { TALLOC_FREE(frame); return NT_STATUS_OK; } p = (const char *)dbuf.dptr; while (next_token_talloc(frame, &p, &string_sid, " ")) { DOM_SID alias; if (!string_to_sid(&alias, string_sid)) continue; status= add_sid_to_array_unique(NULL, &alias, sids, num); if (!NT_STATUS_IS_OK(status)) { goto done; } } done: TALLOC_FREE(frame); return status; }
/* convert a string to a SID, either numeric or username/group */ static BOOL StringToSid(DOM_SID *sid, const char *str) { uint32 *types = NULL; DOM_SID *sids = NULL; BOOL result = True; if (strncmp(str, "S-", 2) == 0) { return string_to_sid(sid, str); } if (!cli_open_policy_hnd() || !NT_STATUS_IS_OK(cli_lsa_lookup_names(cli_ipc, cli_ipc->mem_ctx, &pol, 1, &str, &sids, &types))) { result = False; goto done; } sid_copy(sid, &sids[0]); done: return result; }
/* convert a string to a SID, either numeric or username/group */ static bool StringToSid(struct dom_sid *sid, const char *str) { enum lsa_SidType *types = NULL; struct dom_sid *sids = NULL; bool result = True; if (string_to_sid(sid, str)) { return true; } if (!cli_open_policy_hnd() || !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, talloc_tos(), &pol, 1, &str, NULL, 1, &sids, &types))) { result = False; goto done; } sid_copy(sid, &sids[0]); done: return result; }
static bool sid_in_ignore_list(struct dom_sid * sid, int snum) { const char ** sid_list = NULL; struct dom_sid match; sid_list = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_UNMAPPABLE_SIDS_IGNORE_LIST, PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT); /* Fast path a NULL list */ if (!sid_list || *sid_list == NULL) return false; while (*sid_list) { if (string_to_sid(&match, *sid_list)) if (sid_equal(sid, &match)) return true; sid_list++; } return false; }
static BOOL mappable_sid(const DOM_SID *sid) { DOM_SID domain_sid; if (sid_compare(sid, &global_sid_Builtin_Administrators) == 0) return True; if (sid_compare(sid, &global_sid_World) == 0) return True; if (sid_compare(sid, &global_sid_Authenticated_Users) == 0) return True; if (sid_compare(sid, &global_sid_Builtin_Backup_Operators) == 0) return True; string_to_sid(&domain_sid, "S-1-5-21"); if (sid_compare_domain(sid, &domain_sid) == 0) return True; return False; }
void generate_wellknown_sids(void) { string_to_sid(&global_sid_Builtin, "S-1-5-32"); string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544"); string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545"); string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546"); string_to_sid(&global_sid_World_Domain, "S-1-1"); string_to_sid(&global_sid_World, "S-1-1-0"); string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3"); string_to_sid(&global_sid_Creator_Owner, "S-1-3-0"); string_to_sid(&global_sid_Creator_Group, "S-1-3-1"); string_to_sid(&global_sid_NT_Authority, "S-1-5"); string_to_sid(&global_sid_NULL, "S-1-0-0"); string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11"); string_to_sid(&global_sid_Network, "S-1-5-2"); string_to_sid(&global_sid_Anonymous, "S-1-5-7"); /* Create the anon token. */ sid_copy( &anonymous_token.user_sids[0], &global_sid_World); sid_copy( &anonymous_token.user_sids[1], &global_sid_Network); sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous); }
void generate_wellknown_sids(void) { static BOOL initialised = False; if (initialised) return; /* SECURITY_NULL_SID_AUTHORITY */ string_to_sid(&global_sid_NULL, "S-1-0-0"); /* SECURITY_WORLD_SID_AUTHORITY */ string_to_sid(&global_sid_World_Domain, "S-1-1"); string_to_sid(&global_sid_World, "S-1-1-0"); /* SECURITY_CREATOR_SID_AUTHORITY */ string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3"); string_to_sid(&global_sid_Creator_Owner, "S-1-3-0"); string_to_sid(&global_sid_Creator_Group, "S-1-3-1"); /* SECURITY_NT_AUTHORITY */ string_to_sid(&global_sid_NT_Authority, "S-1-5"); string_to_sid(&global_sid_Network, "S-1-5-2"); string_to_sid(&global_sid_Anonymous, "S-1-5-7"); string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11"); string_to_sid(&global_sid_System, "S-1-5-18"); /* SECURITY_BUILTIN_DOMAIN_RID */ string_to_sid(&global_sid_Builtin, "S-1-5-32"); string_to_sid(&global_sid_Builtin_Administrators, "S-1-5-32-544"); string_to_sid(&global_sid_Builtin_Users, "S-1-5-32-545"); string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546"); string_to_sid(&global_sid_Builtin_Power_Users, "S-1-5-32-547"); string_to_sid(&global_sid_Builtin_Account_Operators, "S-1-5-32-548"); string_to_sid(&global_sid_Builtin_Server_Operators, "S-1-5-32-549"); string_to_sid(&global_sid_Builtin_Print_Operators, "S-1-5-32-550"); string_to_sid(&global_sid_Builtin_Backup_Operators, "S-1-5-32-551"); string_to_sid(&global_sid_Builtin_Replicator, "S-1-5-32-552"); /* Create the anon token. */ sid_copy( &anonymous_token.user_sids[0], &global_sid_World); sid_copy( &anonymous_token.user_sids[1], &global_sid_Network); sid_copy( &anonymous_token.user_sids[2], &global_sid_Anonymous); /* Create the system token. */ sid_copy( &system_token.user_sids[0], &global_sid_System); initialised = True; }
BOOL parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd) { size_t s_size = 0; const char *pacl = acl_str; int num_aces = 0; SEC_ACE *ace_list = NULL; SEC_ACL *psa = NULL; SEC_DESC *psd = NULL; size_t sd_size = 0; int i; *ppsd = NULL; /* If the acl string is blank return "Everyone:R" */ if (!*acl_str) { SEC_DESC *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS); if (!default_psd) { return False; } *ppsd = default_psd; return True; } num_aces = 1; /* Add the number of ',' characters to get the number of aces. */ num_aces += count_chars(pacl,','); ace_list = TALLOC_ARRAY(ctx, SEC_ACE, num_aces); if (!ace_list) { return False; } for (i = 0; i < num_aces; i++) { SEC_ACCESS sa; uint32 g_access; uint32 s_access; DOM_SID sid; fstring sidstr; uint8 type = SEC_ACE_TYPE_ACCESS_ALLOWED; if (!next_token(&pacl, sidstr, ":", sizeof(sidstr))) { DEBUG(0,("parse_usershare_acl: malformed usershare acl looking " "for ':' in string '%s'\n", pacl)); return False; } if (!string_to_sid(&sid, sidstr)) { DEBUG(0,("parse_usershare_acl: failed to convert %s to sid.\n", sidstr )); return False; } switch (*pacl) { case 'F': /* Full Control, ie. R+W */ case 'f': /* Full Control, ie. R+W */ s_access = g_access = GENERIC_ALL_ACCESS; break; case 'R': /* Read only. */ case 'r': /* Read only. */ s_access = g_access = GENERIC_READ_ACCESS; break; case 'D': /* Deny all to this SID. */ case 'd': /* Deny all to this SID. */ type = SEC_ACE_TYPE_ACCESS_DENIED; s_access = g_access = GENERIC_ALL_ACCESS; break; default: DEBUG(0,("parse_usershare_acl: unknown acl type at %s.\n", pacl )); return False; } pacl++; if (*pacl && *pacl != ',') { DEBUG(0,("parse_usershare_acl: bad acl string at %s.\n", pacl )); return False; } pacl++; /* Go past any ',' */ se_map_generic(&s_access, &file_generic_mapping); init_sec_access(&sa, g_access | s_access ); init_sec_ace(&ace_list[i], &sid, type, sa, 0); } if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, num_aces, ace_list)) != NULL) { psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, &sd_size); } if (!psd) { DEBUG(0,("parse_usershare_acl: Failed to make SEC_DESC.\n")); return False; } *ppsd = psd; return True; }
static bool parse_ace(SEC_ACE *ace, const char *orig_str) { char *p; const char *cp; char *tok; unsigned int atype = 0; unsigned int aflags = 0; unsigned int amask = 0; DOM_SID sid; SEC_ACCESS mask; const struct perm_value *v; char *str = SMB_STRDUP(orig_str); TALLOC_CTX *frame = talloc_stackframe(); if (!str) { TALLOC_FREE(frame); return False; } ZERO_STRUCTP(ace); p = strchr_m(str,':'); if (!p) { printf("ACE '%s': missing ':'.\n", orig_str); SAFE_FREE(str); TALLOC_FREE(frame); return False; } *p = '\0'; p++; /* Try to parse numeric form */ if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && string_to_sid(&sid, str)) { goto done; } /* Try to parse text form */ if (!string_to_sid(&sid, str)) { printf("ACE '%s': failed to convert '%s' to SID\n", orig_str, str); SAFE_FREE(str); TALLOC_FREE(frame); return False; } cp = p; if (!next_token_talloc(frame, &cp, &tok, "/")) { printf("ACE '%s': failed to find '/' character.\n", orig_str); SAFE_FREE(str); TALLOC_FREE(frame); return False; } if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { atype = SEC_ACE_TYPE_ACCESS_ALLOWED; } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) { atype = SEC_ACE_TYPE_ACCESS_DENIED; } else { printf("ACE '%s': missing 'ALLOWED' or 'DENIED' entry at '%s'\n", orig_str, tok); SAFE_FREE(str); TALLOC_FREE(frame); return False; } /* Only numeric form accepted for flags at present */ /* no flags on share permissions */ if (!(next_token_talloc(frame, &cp, &tok, "/") && sscanf(tok, "%i", &aflags) && aflags == 0)) { printf("ACE '%s': bad integer flags entry at '%s'\n", orig_str, tok); SAFE_FREE(str); TALLOC_FREE(frame); return False; } if (!next_token_talloc(frame, &cp, &tok, "/")) { printf("ACE '%s': missing / at '%s'\n", orig_str, tok); SAFE_FREE(str); TALLOC_FREE(frame); return False; } if (strncmp(tok, "0x", 2) == 0) { if (sscanf(tok, "%i", &amask) != 1) { printf("ACE '%s': bad hex number at '%s'\n", orig_str, tok); TALLOC_FREE(frame); SAFE_FREE(str); return False; } goto done; } for (v = standard_values; v->perm; v++) { if (strcmp(tok, v->perm) == 0) { amask = v->mask; goto done; } } p = tok; while(*p) { bool found = False; for (v = special_values; v->perm; v++) { if (v->perm[0] == *p) { amask |= v->mask; found = True; } } if (!found) { printf("ACE '%s': bad permission value at '%s'\n", orig_str, p); TALLOC_FREE(frame); SAFE_FREE(str); return False; } p++; } if (*p) { TALLOC_FREE(frame); SAFE_FREE(str); return False; } done: mask = amask; init_sec_ace(ace, &sid, atype, mask, aflags); SAFE_FREE(str); TALLOC_FREE(frame); return True; }
static int set_user_info (struct pdb_methods *in, const char *username, const char *fullname, const char *homedir, const char *acct_desc, const char *drive, const char *script, const char *profile, const char *account_control, const char *user_sid, const char *user_domain, const BOOL badpw, const BOOL hours) { BOOL updated_autolock = False, updated_badpw = False; struct samu *sam_pwent=NULL; BOOL ret; if ( (sam_pwent = samu_new( NULL )) == NULL ) { return 1; } ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username)); if (ret==False) { fprintf (stderr, "Username not found!\n"); TALLOC_FREE(sam_pwent); return -1; } if (hours) { uint8 hours_array[MAX_HOURS_LEN]; uint32 hours_len; hours_len = pdb_get_hours_len(sam_pwent); memset(hours_array, 0xff, hours_len); pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED); } if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) { DEBUG(2,("pdb_update_autolock_flag failed.\n")); } if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) { DEBUG(2,("pdb_update_bad_password_count failed.\n")); } if (fullname) pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED); if (acct_desc) pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED); if (homedir) pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED); if (drive) pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED); if (script) pdb_set_logon_script(sam_pwent, script, PDB_CHANGED); if (profile) pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED); if (user_domain) pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED); if (account_control) { uint32 not_settable = ~(ACB_DISABLED|ACB_HOMDIRREQ|ACB_PWNOTREQ| ACB_PWNOEXP|ACB_AUTOLOCK); uint32 newflag = pdb_decode_acct_ctrl(account_control); if (newflag & not_settable) { fprintf(stderr, "Can only set [NDHLX] flags\n"); TALLOC_FREE(sam_pwent); return -1; } pdb_set_acct_ctrl(sam_pwent, (pdb_get_acct_ctrl(sam_pwent) & not_settable) | newflag, PDB_CHANGED); } if (user_sid) { DOM_SID u_sid; if (!string_to_sid(&u_sid, user_sid)) { /* not a complete sid, may be a RID, try building a SID */ int u_rid; if (sscanf(user_sid, "%d", &u_rid) != 1) { fprintf(stderr, "Error passed string is not a complete user SID or RID!\n"); return -1; } sid_copy(&u_sid, get_global_sam_sid()); sid_append_rid(&u_sid, u_rid); } pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED); } if (badpw) { pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED); pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED); } if (NT_STATUS_IS_OK(in->update_sam_account (in, sam_pwent))) print_user_info (in, username, True, False); else { fprintf (stderr, "Unable to modify entry!\n"); TALLOC_FREE(sam_pwent); return -1; } TALLOC_FREE(sam_pwent); return 0; }
static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *info3, const char *group_sid) { DOM_SID required_membership_sid; DOM_SID *all_sids; size_t num_all_sids = (2 + info3->num_groups2 + info3->num_other_sids); size_t i, j = 0; /* Parse the 'required group' SID */ if (!group_sid || !group_sid[0]) { /* NO sid supplied, all users may access */ return NT_STATUS_OK; } if (!string_to_sid(&required_membership_sid, group_sid)) { DEBUG(0, ("check_info3_in_group: could not parse %s as a SID!", group_sid)); return NT_STATUS_INVALID_PARAMETER; } all_sids = talloc(mem_ctx, sizeof(DOM_SID) * num_all_sids); if (!all_sids) return NT_STATUS_NO_MEMORY; /* and create (by appending rids) the 'domain' sids */ sid_copy(&all_sids[0], &(info3->dom_sid.sid)); if (!sid_append_rid(&all_sids[0], info3->user_rid)) { DEBUG(3,("could not append user's primary RID 0x%x\n", info3->user_rid)); return NT_STATUS_INVALID_PARAMETER; } j++; sid_copy(&all_sids[1], &(info3->dom_sid.sid)); if (!sid_append_rid(&all_sids[1], info3->group_rid)) { DEBUG(3,("could not append additional group rid 0x%x\n", info3->group_rid)); return NT_STATUS_INVALID_PARAMETER; } j++; for (i = 0; i < info3->num_groups2; i++) { sid_copy(&all_sids[j], &(info3->dom_sid.sid)); if (!sid_append_rid(&all_sids[j], info3->gids[j].g_rid)) { DEBUG(3,("could not append additional group rid 0x%x\n", info3->gids[j].g_rid)); return NT_STATUS_INVALID_PARAMETER; } j++; } /* Copy 'other' sids. We need to do sid filtering here to prevent possible elevation of privileges. See: http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp */ for (i = 0; i < info3->num_other_sids; i++) { sid_copy(&all_sids[info3->num_groups2 + i + 2], &info3->other_sids[j].sid); j++; } for (i = 0; i < j; i++) { fstring sid1, sid2; DEBUG(10, ("User has SID: %s\n", sid_to_string(sid1, &all_sids[i]))); if (sid_equal(&required_membership_sid, &all_sids[i])) { DEBUG(10, ("SID %s matches %s - user permitted to authenticate!\n", sid_to_string(sid1, &required_membership_sid), sid_to_string(sid2, &all_sids[i]))); return NT_STATUS_OK; } } /* Do not distinguish this error from a wrong username/pw */ return NT_STATUS_LOGON_FAILURE; }
static bool token_contains_name(TALLOC_CTX *mem_ctx, const char *username, const char *domain, const char *sharename, const struct nt_user_token *token, const char *name) { const char *prefix; DOM_SID sid; enum lsa_SidType type; struct smbd_server_connection *sconn = smbd_server_conn; if (username != NULL) { name = talloc_sub_basic(mem_ctx, username, domain, name); } if (sharename != NULL) { name = talloc_string_sub(mem_ctx, name, "%S", sharename); } if (name == NULL) { /* This is too security sensitive, better panic than return a * result that might be interpreted in a wrong way. */ smb_panic("substitutions failed"); } /* check to see is we already have a SID */ if ( string_to_sid( &sid, name ) ) { DEBUG(5,("token_contains_name: Checking for SID [%s] in token\n", name)); return nt_token_check_sid( &sid, token ); } if (!do_group_checks(&name, &prefix)) { if (!lookup_name_smbconf(mem_ctx, name, LOOKUP_NAME_ALL, NULL, NULL, &sid, &type)) { DEBUG(5, ("lookup_name %s failed\n", name)); return False; } if (type != SID_NAME_USER) { DEBUG(5, ("%s is a %s, expected a user\n", name, sid_type_lookup(type))); return False; } return nt_token_check_sid(&sid, token); } for (/* initialized above */ ; *prefix != '\0'; prefix++) { if (*prefix == '+') { if (!lookup_name_smbconf(mem_ctx, name, LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP, NULL, NULL, &sid, &type)) { DEBUG(5, ("lookup_name %s failed\n", name)); return False; } if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) && (type != SID_NAME_WKN_GRP)) { DEBUG(5, ("%s is a %s, expected a group\n", name, sid_type_lookup(type))); return False; } if (nt_token_check_sid(&sid, token)) { return True; } continue; } if (*prefix == '&') { if (username) { if (user_in_netgroup(sconn, username, name)) { return True; } } continue; } smb_panic("got invalid prefix from do_groups_check"); } return False; }
static NTSTATUS idmap_tdb_id_to_sid(struct idmap_domain *dom, struct id_map *map) { NTSTATUS ret; TDB_DATA data; char *keystr; struct idmap_tdb_context *ctx; if (!dom || !map) { return NT_STATUS_INVALID_PARAMETER; } ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); /* apply filters before checking */ if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", map->xid.id, dom->low_id, dom->high_id)); return NT_STATUS_NONE_MAPPED; } switch (map->xid.type) { case ID_TYPE_UID: keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id); break; case ID_TYPE_GID: keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id); break; default: DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); return NT_STATUS_INVALID_PARAMETER; } /* final SAFE_FREE safe */ data.dptr = NULL; if (keystr == NULL) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } DEBUG(10,("Fetching record %s\n", keystr)); /* Check if the mapping exists */ ret = dbwrap_fetch_bystring(ctx->db, NULL, keystr, &data); if (!NT_STATUS_IS_OK(ret)) { DEBUG(10,("Record %s not found\n", keystr)); ret = NT_STATUS_NONE_MAPPED; goto done; } if (!string_to_sid(map->sid, (const char *)data.dptr)) { DEBUG(10,("INVALID SID (%s) in record %s\n", (const char *)data.dptr, keystr)); ret = NT_STATUS_INTERNAL_DB_ERROR; goto done; } DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr)); ret = NT_STATUS_OK; done: talloc_free(data.dptr); talloc_free(keystr); return ret; }
/********************************************************* Add New User **********************************************************/ static int new_user (struct pdb_methods *in, const char *username, const char *fullname, const char *homedir, const char *drive, const char *script, const char *profile, char *user_sid, BOOL stdin_get) { struct samu *sam_pwent; char *password1, *password2; int rc_pwd_cmp; struct passwd *pwd; get_global_sam_sid(); if ( !(pwd = getpwnam_alloc( NULL, username )) ) { DEBUG(0,("Cannot locate Unix account for %s\n", username)); return -1; } if ( (sam_pwent = samu_new( NULL )) == NULL ) { DEBUG(0, ("Memory allocation failure!\n")); return -1; } if (!NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd ))) { TALLOC_FREE( sam_pwent ); TALLOC_FREE( pwd ); DEBUG(0, ("could not create account to add new user %s\n", username)); return -1; } password1 = get_pass( "new password:"******"retype new password:"******"Passwords do not match!\n"); TALLOC_FREE(sam_pwent); } else { pdb_set_plaintext_passwd(sam_pwent, password1); } memset(password1, 0, strlen(password1)); SAFE_FREE(password1); memset(password2, 0, strlen(password2)); SAFE_FREE(password2); /* pwds do _not_ match? */ if (rc_pwd_cmp) return -1; if (fullname) pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED); if (homedir) pdb_set_homedir (sam_pwent, homedir, PDB_CHANGED); if (drive) pdb_set_dir_drive (sam_pwent, drive, PDB_CHANGED); if (script) pdb_set_logon_script(sam_pwent, script, PDB_CHANGED); if (profile) pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED); if (user_sid) { DOM_SID u_sid; if (!string_to_sid(&u_sid, user_sid)) { /* not a complete sid, may be a RID, try building a SID */ int u_rid; if (sscanf(user_sid, "%d", &u_rid) != 1) { fprintf(stderr, "Error passed string is not a complete user SID or RID!\n"); TALLOC_FREE(sam_pwent); return -1; } sid_copy(&u_sid, get_global_sam_sid()); sid_append_rid(&u_sid, u_rid); } pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED); } pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL, PDB_CHANGED); if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) { print_user_info (in, username, True, False); } else { fprintf (stderr, "Unable to add user! (does it already exist?)\n"); TALLOC_FREE(sam_pwent); return -1; } TALLOC_FREE(sam_pwent); return 0; }
static void parse_samsync_partial_replication_objects(TALLOC_CTX *mem_ctx, int argc, const char **argv, bool *do_single_object_replication, struct samsync_object **objects, uint32_t *num_objects) { int i; if (argc > 0) { *do_single_object_replication = true; } for (i=0; i<argc; i++) { struct samsync_object o; ZERO_STRUCT(o); if (!StrnCaseCmp(argv[i], "user_rid=", strlen("user_rid="))) { o.object_identifier.rid = get_int_param(argv[i]); o.object_type = NETR_DELTA_USER; o.database_id = SAM_DATABASE_DOMAIN; } if (!StrnCaseCmp(argv[i], "group_rid=", strlen("group_rid="))) { o.object_identifier.rid = get_int_param(argv[i]); o.object_type = NETR_DELTA_GROUP; o.database_id = SAM_DATABASE_DOMAIN; } if (!StrnCaseCmp(argv[i], "group_member_rid=", strlen("group_member_rid="))) { o.object_identifier.rid = get_int_param(argv[i]); o.object_type = NETR_DELTA_GROUP_MEMBER; o.database_id = SAM_DATABASE_DOMAIN; } if (!StrnCaseCmp(argv[i], "alias_rid=", strlen("alias_rid="))) { o.object_identifier.rid = get_int_param(argv[i]); o.object_type = NETR_DELTA_ALIAS; o.database_id = SAM_DATABASE_BUILTIN; } if (!StrnCaseCmp(argv[i], "alias_member_rid=", strlen("alias_member_rid="))) { o.object_identifier.rid = get_int_param(argv[i]); o.object_type = NETR_DELTA_ALIAS_MEMBER; o.database_id = SAM_DATABASE_BUILTIN; } if (!StrnCaseCmp(argv[i], "account_sid=", strlen("account_sid="))) { const char *sid_str = get_string_param(argv[i]); string_to_sid(&o.object_identifier.sid, sid_str); o.object_type = NETR_DELTA_ACCOUNT; o.database_id = SAM_DATABASE_PRIVS; } if (!StrnCaseCmp(argv[i], "policy_sid=", strlen("policy_sid="))) { const char *sid_str = get_string_param(argv[i]); string_to_sid(&o.object_identifier.sid, sid_str); o.object_type = NETR_DELTA_POLICY; o.database_id = SAM_DATABASE_PRIVS; } if (!StrnCaseCmp(argv[i], "trustdom_sid=", strlen("trustdom_sid="))) { const char *sid_str = get_string_param(argv[i]); string_to_sid(&o.object_identifier.sid, sid_str); o.object_type = NETR_DELTA_TRUSTED_DOMAIN; o.database_id = SAM_DATABASE_PRIVS; } if (!StrnCaseCmp(argv[i], "secret_name=", strlen("secret_name="))) { o.object_identifier.name = get_string_param(argv[i]); o.object_type = NETR_DELTA_SECRET; o.database_id = SAM_DATABASE_PRIVS; } if (o.object_type > 0) { ADD_TO_ARRAY(mem_ctx, struct samsync_object, o, objects, num_objects); } } }
enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) { DOM_SID sid; uint32 flags = 0x0; /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid, state->request.data.sid)); if (!string_to_sid(&sid, state->request.data.sid)) { DEBUG(1, ("Could not cvt string to sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; } /* This gets a little tricky. If we assume that usernames are syncd between /etc/passwd and the windows domain (such as a member of a Samba domain), the we need to get the uid from the OS and not alocate one ourselves */ if ( lp_winbind_trusted_domains_only() ) { struct winbindd_domain *domain = NULL; DOM_SID sid2; uint32 rid; unid_t id; domain = find_our_domain(); if ( !domain ) { DEBUG(0,("winbindd_sid_to_uid: can't find my own domain!\n")); return WINBINDD_ERROR; } sid_copy( &sid2, &sid ); sid_split_rid( &sid2, &rid ); if ( sid_equal( &sid2, &domain->sid ) ) { fstring domain_name; fstring group; enum SID_NAME_USE type; struct group *grp = NULL; /* ok...here's we know that we are dealing with our own domain (the one to which we are joined). And we know that there must be a UNIX account for this group. So we lookup the sid and the call getpwnam().*/ /* But first check and see if we don't already have a mapping */ flags = ID_QUERY_ONLY; if ( NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) return WINBINDD_OK; /* now fall back to the hard way */ if ( !winbindd_lookup_name_by_sid(&sid, domain_name, group, &type) ) return WINBINDD_ERROR; if ( !(grp = sys_getgrnam(group)) ) { DEBUG(0,("winbindd_sid_to_uid: 'winbind trusted domains only' is " "set but this group [%s] doesn't exist!\n", group)); return WINBINDD_ERROR; } state->response.data.gid = grp->gr_gid; id.gid = grp->gr_gid; idmap_set_mapping( &sid, id, ID_GROUPID ); return WINBINDD_OK; } } if ( state->request.flags & WBFLAG_QUERY_ONLY ) flags = ID_QUERY_ONLY; /* Find gid for this sid and return it */ if ( !NT_STATUS_IS_OK(idmap_sid_to_gid(&sid, &(state->response.data.gid), flags)) ) { DEBUG(1, ("Could not get gid for sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; } return WINBINDD_OK; }
static NTSTATUS cmd_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, char **argv) { POLICY_HND connect_pol, domain_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 user_rid, num_aliases, *alias_rids; int i; fstring server; DOM_SID tmp_sid; DOM_SID2 sid; DOM_SID global_sid_Builtin; string_to_sid(&global_sid_Builtin, "S-1-5-32"); if (argc != 3) { printf("Usage: %s builtin|domain rid\n", argv[0]); return NT_STATUS_OK; } sscanf(argv[2], "%i", &user_rid); slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } if (StrCaseCmp(argv[1], "domain")==0) result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol); else if (StrCaseCmp(argv[1], "builtin")==0) result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &global_sid_Builtin, &domain_pol); else return NT_STATUS_OK; if (!NT_STATUS_IS_OK(result)) { goto done; } sid_copy(&tmp_sid, &domain_sid); sid_append_rid(&tmp_sid, user_rid); init_dom_sid2(&sid, &tmp_sid); result = cli_samr_query_useraliases(cli, mem_ctx, &domain_pol, 1, &sid, &num_aliases, &alias_rids); if (!NT_STATUS_IS_OK(result)) { goto done; } for (i = 0; i < num_aliases; i++) { printf("\tgroup rid:[0x%x]\n", alias_rids[i]); } done: return result; }
static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, int argc, char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; POLICY_HND connect_pol, domain_pol; uint32 flags = 0x000003e8; /* Unknown */ uint32 num_rids, num_names, *name_types, *rids; const char **names; int i; DOM_SID global_sid_Builtin; string_to_sid(&global_sid_Builtin, "S-1-5-32"); if (argc < 3) { printf("Usage: %s domain|builtin name1 [name2 [name3] [...]]\n", argv[0]); printf("check on the domain SID: S-1-5-21-x-y-z\n"); printf("or check on the builtin SID: S-1-5-32\n"); return NT_STATUS_OK; } /* Get sam policy and domain handles */ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, &connect_pol); if (!NT_STATUS_IS_OK(result)) { goto done; } if (StrCaseCmp(argv[1], "domain")==0) result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &domain_sid, &domain_pol); else if (StrCaseCmp(argv[1], "builtin")==0) result = cli_samr_open_domain(cli, mem_ctx, &connect_pol, MAXIMUM_ALLOWED_ACCESS, &global_sid_Builtin, &domain_pol); else return NT_STATUS_OK; if (!NT_STATUS_IS_OK(result)) { goto done; } /* Look up names */ num_names = argc - 2; names = (const char **)talloc(mem_ctx, sizeof(char *) * num_names); for (i = 0; i < argc - 2; i++) names[i] = argv[i + 2]; result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, flags, num_names, names, &num_rids, &rids, &name_types); if (!NT_STATUS_IS_OK(result)) { goto done; } /* Display results */ for (i = 0; i < num_names; i++) printf("name %s: 0x%x (%d)\n", names[i], rids[i], name_types[i]); done: return result; }
static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) { LDAPMessage *entry = NULL; NTSTATUS ret; TALLOC_CTX *memctx; struct idmap_ldap_context *ctx; LDAPMessage *result = NULL; const char *uidNumber; const char *gidNumber; const char **attr_list; char *filter = NULL; bool multi = False; int idx = 0; int bidx = 0; int count; int rc; int i; /* Only do query if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context); memctx = talloc_new(ctx); if ( ! memctx) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER); gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER); attr_list = get_attr_list(memctx, sidmap_attr_list); if ( ! ids[1]) { /* if we are requested just one mapping use the simple filter */ filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_string_talloc(memctx, ids[0]->sid)); CHECK_ALLOC_DONE(filter); DEBUG(10, ("Filter: [%s]\n", filter)); } else { /* multiple mappings */ multi = True; } for (i = 0; ids[i]; i++) { ids[i]->status = ID_UNKNOWN; } again: if (multi) { TALLOC_FREE(filter); filter = talloc_asprintf(memctx, "(&(objectClass=%s)(|", LDAP_OBJ_IDMAP_ENTRY); CHECK_ALLOC_DONE(filter); bidx = idx; for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) { filter = talloc_asprintf_append_buffer(filter, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_string_talloc(memctx, ids[idx]->sid)); CHECK_ALLOC_DONE(filter); } filter = talloc_asprintf_append_buffer(filter, "))"); CHECK_ALLOC_DONE(filter); DEBUG(10, ("Filter: [%s]", filter)); } else { bidx = 0; idx = 1; } rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE, filter, attr_list, 0, &result); if (rc != LDAP_SUCCESS) { DEBUG(3,("Failure looking up sids (%s)\n", ldap_err2string(rc))); ret = NT_STATUS_UNSUCCESSFUL; goto done; } count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result); if (count == 0) { DEBUG(10, ("NO SIDs found\n")); } for (i = 0; i < count; i++) { char *sidstr = NULL; char *tmp = NULL; enum id_type type; struct id_map *map; struct dom_sid sid; uint32_t id; if (i == 0) { /* first entry */ entry = ldap_first_entry(ctx->smbldap_state->ldap_struct, result); } else { /* following ones */ entry = ldap_next_entry(ctx->smbldap_state->ldap_struct, entry); } if ( ! entry) { DEBUG(2, ("ERROR: Unable to fetch ldap entries " "from results\n")); break; } /* first check if the SID is present */ sidstr = smbldap_talloc_single_attribute( ctx->smbldap_state->ldap_struct, entry, LDAP_ATTRIBUTE_SID, memctx); if ( ! sidstr) { /* no sid ??, skip entry */ DEBUG(2, ("WARNING SID not found on entry\n")); continue; } if ( ! string_to_sid(&sid, sidstr)) { DEBUG(2, ("ERROR: Invalid SID on entry\n")); TALLOC_FREE(sidstr); continue; } map = idmap_find_map_by_sid(&ids[bidx], &sid); if (!map) { DEBUG(2, ("WARNING: couldn't find entry sid (%s) " "in ids", sidstr)); TALLOC_FREE(sidstr); continue; } /* now try to see if it is a uid, if not try with a gid * (gid is more common, but in case both uidNumber and * gidNumber are returned the SID is mapped to the uid * not the gid) */ type = ID_TYPE_UID; tmp = smbldap_talloc_single_attribute( ctx->smbldap_state->ldap_struct, entry, uidNumber, memctx); if ( ! tmp) { type = ID_TYPE_GID; tmp = smbldap_talloc_single_attribute( ctx->smbldap_state->ldap_struct, entry, gidNumber, memctx); } if ( ! tmp) { /* no ids ?? */ DEBUG(5, ("no uidNumber, " "nor gidNumber attributes found\n")); TALLOC_FREE(sidstr); continue; } id = strtoul(tmp, NULL, 10); if (!idmap_unix_id_is_in_range(id, dom)) { DEBUG(5, ("Requested id (%u) out of range (%u - %u). " "Filtered!\n", id, dom->low_id, dom->high_id)); TALLOC_FREE(sidstr); TALLOC_FREE(tmp); continue; } TALLOC_FREE(tmp); if (map->status == ID_MAPPED) { DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. " "overwriting mapping %s -> %u with %s -> %u\n", (type == ID_TYPE_UID) ? "UID" : "GID", sidstr, map->xid.id, sidstr, id)); } TALLOC_FREE(sidstr); /* mapped */ map->xid.type = type; map->xid.id = id; map->status = ID_MAPPED; DEBUG(10, ("Mapped %s -> %lu (%d)\n", sid_string_dbg(map->sid), (unsigned long)map->xid.id, map->xid.type)); } /* free the ldap results */ if (result) { ldap_msgfree(result); result = NULL; } if (multi && ids[idx]) { /* still some values to map */ goto again; } /* * try to create new mappings for unmapped sids */ for (i = 0; ids[i]; i++) { if (ids[i]->status != ID_MAPPED) { ids[i]->status = ID_UNMAPPED; if (ids[i]->sid != NULL) { ret = idmap_ldap_new_mapping(dom, ids[i]); if (!NT_STATUS_IS_OK(ret)) { goto done; } } } } ret = NT_STATUS_OK; done: talloc_free(memctx); return ret; }
static NTSTATUS cmd_lsa_lookup_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { struct policy_handle pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID *sids; char **domains; char **names; enum lsa_SidType *types; int i; if (argc == 1) { printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]); return NT_STATUS_OK; } result = rpccli_lsa_open_policy(cli, mem_ctx, True, SEC_FLAG_MAXIMUM_ALLOWED, &pol); if (!NT_STATUS_IS_OK(result)) goto done; /* Convert arguments to sids */ sids = TALLOC_ARRAY(mem_ctx, DOM_SID, argc - 1); if (!sids) { printf("could not allocate memory for %d sids\n", argc - 1); goto done; } for (i = 0; i < argc - 1; i++) if (!string_to_sid(&sids[i], argv[i + 1])) { result = NT_STATUS_INVALID_SID; goto done; } /* Lookup the SIDs */ result = rpccli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids, &domains, &names, &types); if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) goto done; result = NT_STATUS_OK; /* Print results */ for (i = 0; i < (argc - 1); i++) { fstring sid_str; sid_to_fstring(sid_str, &sids[i]); printf("%s %s\\%s (%d)\n", sid_str, domains[i] ? domains[i] : "*unknown*", names[i] ? names[i] : "*unknown*", types[i]); } rpccli_lsa_Close(cli, mem_ctx, &pol); done: return result; }
int main( int argc, char *argv[] ) { TALLOC_CTX *frame = talloc_stackframe(); int opt; REGF_FILE *infile, *outfile; REGF_NK_REC *nk; char *orig_filename, *new_filename; struct poptOption long_options[] = { POPT_AUTOHELP { "change-sid", 'c', POPT_ARG_STRING, NULL, 'c', "Provides SID to change" }, { "new-sid", 'n', POPT_ARG_STRING, NULL, 'n', "Provides SID to change to" }, { "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 'v', "Verbose output" }, POPT_COMMON_SAMBA POPT_COMMON_VERSION POPT_TABLEEND }; poptContext pc; load_case_tables(); /* setup logging options */ setup_logging( "profiles", DEBUG_STDERR); pc = poptGetContext("profiles", argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "<profilefile>"); /* Now, process the arguments */ while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'c': change = 1; if (!string_to_sid(&old_sid, poptGetOptArg(pc))) { fprintf(stderr, "Argument to -c should be a SID in form of S-1-5-...\n"); poptPrintUsage(pc, stderr, 0); exit(254); } break; case 'n': new_val = 1; if (!string_to_sid(&new_sid, poptGetOptArg(pc))) { fprintf(stderr, "Argument to -n should be a SID in form of S-1-5-...\n"); poptPrintUsage(pc, stderr, 0); exit(253); } break; } } poptGetArg(pc); if (!poptPeekArg(pc)) { poptPrintUsage(pc, stderr, 0); exit(1); } if ((!change && new_val) || (change && !new_val)) { fprintf(stderr, "You must specify both -c and -n if one or the other is set!\n"); poptPrintUsage(pc, stderr, 0); exit(252); } orig_filename = talloc_strdup(frame, poptPeekArg(pc)); if (!orig_filename) { exit(ENOMEM); } new_filename = talloc_asprintf(frame, "%s.new", orig_filename); if (!new_filename) { exit(ENOMEM); } if (!(infile = regfio_open( orig_filename, O_RDONLY, 0))) { fprintf( stderr, "Failed to open %s!\n", orig_filename ); fprintf( stderr, "Error was (%s)\n", strerror(errno) ); exit (1); } if ( !(outfile = regfio_open( new_filename, (O_RDWR|O_CREAT|O_TRUNC), (S_IRUSR|S_IWUSR) )) ) { fprintf( stderr, "Failed to open new file %s!\n", new_filename ); fprintf( stderr, "Error was (%s)\n", strerror(errno) ); exit (1); } /* actually do the update now */ if ((nk = regfio_rootkey( infile )) == NULL) { fprintf(stderr, "Could not get rootkey\n"); exit(3); } if (!copy_registry_tree( infile, nk, NULL, outfile, "")) { fprintf(stderr, "Failed to write updated registry file!\n"); exit(2); } /* cleanup */ regfio_close(infile); regfio_close(outfile); poptFreeContext(pc); TALLOC_FREE(frame); return 0; }
static int ADC_client_on_recv_line(struct ADC_client* client, const char* line, size_t length) { struct ADC_chat_message chat; struct ADC_client_callback_data data; ADC_TRACE; #ifdef ADC_CLIENT_DEBUG_PROTO ADC_client_debug(client, "- LINE: '%s'", line); #endif /* Parse message */ struct adc_message* msg = adc_msg_parse(line, length); if (!msg) { ADC_client_debug(client, "WARNING: Message cannot be decoded: \"%s\"", line); return -1; } if (length < 4) { ADC_client_debug(client, "Unexpected response from hub: '%s'", line); return -1; } switch (msg->cmd) { case ADC_CMD_ISUP: break; case ADC_CMD_ISID: if (client->state == ps_protocol) { client->sid = string_to_sid(&line[5]); client->callback(client, ADC_CLIENT_LOGGING_IN, 0); ADC_client_set_state(client, ps_identify); ADC_client_send_info(client); } break; case ADC_CMD_BMSG: case ADC_CMD_EMSG: case ADC_CMD_DMSG: case ADC_CMD_IMSG: { chat.from_sid = msg->source; chat.to_sid = msg->target; data.chat = &chat; EXTRACT_POS_ARG(msg, 0, chat.message); chat.flags = 0; if (adc_msg_has_named_argument(msg, ADC_MSG_FLAG_ACTION)) chat.flags |= chat_flags_action; if (adc_msg_has_named_argument(msg, ADC_MSG_FLAG_PRIVATE)) chat.flags |= chat_flags_private; client->callback(client, ADC_CLIENT_MESSAGE, &data); hub_free(chat.message); break; } case ADC_CMD_IINF: { struct ADC_hub_info hubinfo; EXTRACT_NAMED_ARG(msg, "NI", hubinfo.name); EXTRACT_NAMED_ARG(msg, "DE", hubinfo.description); EXTRACT_NAMED_ARG(msg, "VE", hubinfo.version); struct ADC_client_callback_data data; data.hubinfo = &hubinfo; client->callback(client, ADC_CLIENT_HUB_INFO, &data); hub_free(hubinfo.name); hub_free(hubinfo.description); hub_free(hubinfo.version); break; } case ADC_CMD_BSCH: case ADC_CMD_FSCH: { client->callback(client, ADC_CLIENT_SEARCH_REQ, 0); break; } case ADC_CMD_BINF: { if (msg->source == client->sid) { if (client->state == ps_verify || client->state == ps_identify) { ADC_client_on_login(client); } } else { if (adc_msg_has_named_argument(msg, "ID")) { struct ADC_user user; user.sid = msg->source; EXTRACT_NAMED_ARG_X(msg, "NI", user.name, sizeof(user.name)); EXTRACT_NAMED_ARG_X(msg, "DE", user.description, sizeof(user.description)); EXTRACT_NAMED_ARG_X(msg, "VE", user.version, sizeof(user.version)); EXTRACT_NAMED_ARG_X(msg, "ID", user.cid, sizeof(user.cid)); EXTRACT_NAMED_ARG_X(msg, "I4", user.address, sizeof(user.address)); struct ADC_client_callback_data data; data.user = &user; client->callback(client, ADC_CLIENT_USER_JOIN, &data); } } } break; case ADC_CMD_IQUI: { struct ADC_client_quit_reason reason; memset(&reason, 0, sizeof(reason)); reason.sid = string_to_sid(&line[5]); if (adc_msg_has_named_argument(msg, ADC_QUI_FLAG_DISCONNECT)) reason.flags |= 1; data.quit = &reason; client->callback(client, ADC_CLIENT_USER_QUIT, &data); break; } case ADC_CMD_ISTA: /* if (strncmp(line, "ISTA 000", 8)) { ADC_client_debug(client, "status: '%s'\n", (start + 9)); } */ break; default: break; } adc_msg_free(msg); return 0; }
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; }
/******************************************************************* Process command line options ******************************************************************/ static void process_options(int argc, char **argv, BOOL amroot) { int ch; DOM_SID dom_sid; fstring sid_str; user_name[0] = '\0'; while ((ch = getopt(argc, argv, "c:axdehmnj:t:r:sw:R:D:U:LSW:X:")) != EOF) { switch(ch) { case 'L': local_mode = amroot = True; break; case 'c': pstrcpy(servicesf,optarg); break; case 'a': if (!amroot) goto bad_args; local_flags |= LOCAL_ADD_USER; break; case 'x': if (!amroot) goto bad_args; local_flags |= LOCAL_DELETE_USER; new_passwd = strdup_x("XXXXXX"); break; case 'd': if (!amroot) goto bad_args; local_flags |= LOCAL_DISABLE_USER; new_passwd = strdup_x("XXXXXX"); break; case 'e': if (!amroot) goto bad_args; local_flags |= LOCAL_ENABLE_USER; break; case 'm': if (!amroot) goto bad_args; local_flags |= LOCAL_TRUST_ACCOUNT; break; case 'n': if (!amroot) goto bad_args; local_flags |= LOCAL_SET_NO_PASSWORD; new_passwd = strdup_x("NO PASSWORD"); break; case 'j': if (!amroot) goto bad_args; new_domain = optarg; strupper(new_domain); joining_domain = True; break; case 't': if (!amroot) goto bad_args; new_domain = optarg; strupper(new_domain); changing_trust_pw = True; break; case 'r': remote_machine = optarg; break; case 'S': if (!amroot) goto bad_args; local_flags |= LOCAL_GET_DOM_SID; break; case 's': set_line_buffering(stdin); set_line_buffering(stdout); set_line_buffering(stderr); stdin_passwd_get = True; break; case 'w': if (!amroot) goto bad_args; #ifdef WITH_LDAP_SAM local_flags |= LOCAL_SET_LDAP_ADMIN_PW; fstrcpy(ldap_secret, optarg); break; #else printf("-w not available unless configured --with-ldapsam\n"); goto bad_args; #endif case 'R': if (!amroot) goto bad_args; lp_set_name_resolve_order(optarg); break; case 'D': DEBUGLEVEL = atoi(optarg); break; case 'U': { char *lp; got_username = True; fstrcpy(user_name, optarg); if ((lp = strchr(user_name, '%'))) { *lp = 0; fstrcpy(user_password, lp + 1); got_pass = True; memset(strchr(optarg, '%') + 1, 'X', strlen(user_password)); } } break; case 'W': /* Take the SID on the command line and make it ours */ if (!lp_load(servicesf,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); exit(1); } if (!string_to_sid(&dom_sid, optarg)) { fprintf(stderr, "Invalid SID: %s\n", optarg); exit(1); } if (!secrets_init()) { fprintf(stderr, "Unable to open secrets database!\n"); exit(1); } if (!secrets_store_domain_sid(global_myname, &dom_sid)) { fprintf(stderr, "Unable to write the new SID %s as the server SID for %s\n", optarg, global_myname); exit(1); } /* * Now, write it to the workgroup as well, to make * things consistent. This is a risk however. */ if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) { fprintf(stderr, "Unable to write the new SID %s as the domain SID for %s\n", optarg, lp_workgroup()); exit(1); } exit(0); break; case 'X': /* Extract the SID for a domain from secrets */ if (!lp_load(servicesf,True,False,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); exit(1); } if (!secrets_init()) { fprintf(stderr, "Unable to open secrets database!\n"); exit(1); } if (secrets_fetch_domain_sid(optarg, &dom_sid)) { sid_to_string(sid_str, &dom_sid); printf("SID for domain %s is: %s\n", optarg, sid_str); exit(0); } else { fprintf(stderr, "Could not retrieve SID for domain: %s\n", optarg); exit(1); } break; case 'h': default: bad_args: usage(); } } argc -= optind; argv += optind; if (joining_domain && (argc != 0)) usage(); switch(argc) { case 0: if (!got_username) fstrcpy(user_name, ""); break; case 1: if (!amroot == 1) { new_passwd = argv[0]; break; } if (got_username) usage(); fstrcpy(user_name, argv[0]); break; case 2: if (!amroot || got_username || got_pass) usage(); fstrcpy(user_name, argv[0]); new_passwd = strdup_x(argv[1]); break; default: usage(); } }
static NTSTATUS cmd_lsa_lookup_sids3(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; int i; struct lsa_SidArray sids; struct lsa_RefDomainList *domains; struct lsa_TransNameArray2 names; uint32_t count = 0; if (argc == 1) { printf("Usage: %s [sid1 [sid2 [...]]]\n", argv[0]); return NT_STATUS_OK; } ZERO_STRUCT(names); /* Convert arguments to sids */ sids.num_sids = argc-1; sids.sids = talloc_array(mem_ctx, struct lsa_SidPtr, sids.num_sids); if (!sids.sids) { printf("could not allocate memory for %d sids\n", sids.num_sids); goto done; } for (i = 0; i < sids.num_sids; i++) { sids.sids[i].sid = talloc(sids.sids, struct dom_sid); if (sids.sids[i].sid == NULL) { result = NT_STATUS_NO_MEMORY; goto done; } if (!string_to_sid(sids.sids[i].sid, argv[i+1])) { result = NT_STATUS_INVALID_SID; goto done; } } /* Lookup the SIDs */ result = rpccli_lsa_LookupSids3(cli, mem_ctx, &sids, &domains, &names, 1, &count, 0, 0); if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) goto done; result = NT_STATUS_OK; /* Print results */ for (i = 0; i < count; i++) { fstring sid_str; sid_to_fstring(sid_str, sids.sids[i].sid); printf("%s %s (%d)\n", sid_str, names.names[i].name.string, names.names[i].sid_type); } done: return result; }
static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx, BOOL positive, const char *name, uint32 rights) { DOM_SID sid; enum lsa_SidType type; struct afs_ace *result; if (strcmp(name, "system:administrators") == 0) { sid_copy(&sid, &global_sid_Builtin_Administrators); type = SID_NAME_ALIAS; } else if (strcmp(name, "system:anyuser") == 0) { sid_copy(&sid, &global_sid_World); type = SID_NAME_ALIAS; } else if (strcmp(name, "system:authuser") == 0) { sid_copy(&sid, &global_sid_Authenticated_Users); type = SID_NAME_WKN_GRP; } else if (strcmp(name, "system:backup") == 0) { sid_copy(&sid, &global_sid_Builtin_Backup_Operators); type = SID_NAME_ALIAS; } else if (sidpts) { /* All PTS users/groups are expressed as SIDs */ sid_copy(&sid, &global_sid_NULL); type = SID_NAME_UNKNOWN; if (string_to_sid(&sid, name)) { const char *user, *domain; /* We have to find the type, look up the SID */ lookup_sid(tmp_talloc_ctx(), &sid, &domain, &user, &type); } } else { const char *domain, *uname; char *p; p = strchr_m(name, *lp_winbind_separator()); if (p != NULL) { *p = '\\'; } if (!lookup_name(tmp_talloc_ctx(), name, LOOKUP_NAME_ALL, &domain, &uname, &sid, &type)) { DEBUG(10, ("Could not find AFS user %s\n", name)); sid_copy(&sid, &global_sid_NULL); type = SID_NAME_UNKNOWN; } } result = TALLOC_P(mem_ctx, struct afs_ace); if (result == NULL) { DEBUG(0, ("Could not talloc AFS ace\n")); return NULL; } result->name = talloc_strdup(mem_ctx, name); if (result->name == NULL) { DEBUG(0, ("Could not talloc AFS ace name\n")); return NULL; } result->sid = sid; result->type = type; result->positive = positive; result->rights = rights; return result; }