static NTSTATUS gpo_prepare_local_store(TALLOC_CTX *mem_ctx, const char *unix_path) { const char *top_dir = lock_path(GPO_CACHE_DIR); char *current_dir; char *tok; current_dir = talloc_strdup(mem_ctx, top_dir); NT_STATUS_HAVE_NO_MEMORY(current_dir); if ((mkdir(top_dir, 0644)) < 0 && errno != EEXIST) { return NT_STATUS_ACCESS_DENIED; } while (next_token_talloc(mem_ctx, &unix_path, &tok, "/")) { if (strequal(tok, GPO_CACHE_DIR)) { break; } } while (next_token_talloc(mem_ctx, &unix_path, &tok, "/")) { current_dir = talloc_asprintf_append_buffer(current_dir, "/%s", tok); NT_STATUS_HAVE_NO_MEMORY(current_dir); if ((mkdir(current_dir, 0644)) < 0 && errno != EEXIST) { return NT_STATUS_ACCESS_DENIED; } } return NT_STATUS_OK; }
NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx, const char *cache_dir, const char *file_sys_path, char **server, char **service, char **nt_path, char **unix_path) { char *path = NULL; *server = NULL; *service = NULL; *nt_path = NULL; *unix_path = NULL; if (!file_sys_path) { return NT_STATUS_OK; } if (!next_token_talloc(mem_ctx, &file_sys_path, server, "\\")) { return NT_STATUS_INVALID_PARAMETER; } NT_STATUS_HAVE_NO_MEMORY(*server); if (!next_token_talloc(mem_ctx, &file_sys_path, service, "\\")) { return NT_STATUS_INVALID_PARAMETER; } NT_STATUS_HAVE_NO_MEMORY(*service); if ((*nt_path = talloc_asprintf(mem_ctx, "\\%s", file_sys_path)) == NULL) { return NT_STATUS_NO_MEMORY; } NT_STATUS_HAVE_NO_MEMORY(*nt_path); if ((path = talloc_asprintf(mem_ctx, "%s/%s", cache_dir, file_sys_path)) == NULL) { return NT_STATUS_NO_MEMORY; } path = talloc_string_sub(mem_ctx, path, "\\", "/"); if (!path) { return NT_STATUS_NO_MEMORY; } *unix_path = talloc_strdup(mem_ctx, path); NT_STATUS_HAVE_NO_MEMORY(*unix_path); talloc_free(path); return NT_STATUS_OK; }
static int talktochild(int master, const char *seq) { TALLOC_CTX *frame = talloc_stackframe(); int count = 0; char *issue; char *expected; issue = talloc_strdup(frame, "."); if (!issue) { TALLOC_FREE(frame); return false; } while (next_token_talloc(frame, &seq, &expected, NULL)) { pwd_sub(expected); count++; if (!expect(master, issue, expected)) { DEBUG(3, ("Response %d incorrect\n", count)); TALLOC_FREE(frame); return false; } if (!next_token_talloc(frame, &seq, &issue, NULL)) { issue = talloc_strdup(frame, "."); if (!issue) { TALLOC_FREE(frame); return false; } } pwd_sub(issue); } if (!strequal(issue, ".")) { /* we have one final issue to send */ expected = talloc_strdup(frame, "."); if (!expected) { TALLOC_FREE(frame); return false; } if (!expect(master, issue, expected)) { TALLOC_FREE(frame); return False; } } TALLOC_FREE(frame); return (count > 0); }
void set_socket_options(int fd, const char *options) { TALLOC_CTX *ctx = talloc_new(NULL); char *tok; while (next_token_talloc(ctx, &options, &tok," \t,")) { int ret=0,i; int value = 1; char *p; bool got_value = false; if ((p = strchr_m(tok,'='))) { *p = 0; value = atoi(p+1); got_value = true; } for (i=0;socket_options[i].name;i++) if (strequal(socket_options[i].name,tok)) break; if (!socket_options[i].name) { DEBUG(0,("Unknown socket option %s\n",tok)); continue; } switch (socket_options[i].opttype) { case OPT_BOOL: case OPT_INT: ret = setsockopt(fd,socket_options[i].level, socket_options[i].option, (char *)&value,sizeof(int)); break; case OPT_ON: if (got_value) DEBUG(0,("syntax error - %s " "does not take a value\n",tok)); { int on = socket_options[i].value; ret = setsockopt(fd,socket_options[i].level, socket_options[i].option, (char *)&on,sizeof(int)); } break; } if (ret != 0) { /* be aware that some systems like Solaris return * EINVAL to a setsockopt() call when the client * sent a RST previously - no need to worry */ DEBUG(2,("Failed to set socket option %s (Error %s)\n", tok, strerror(errno) )); } } TALLOC_FREE(ctx); print_socket_options(fd); }
static void complete_sync(struct sync_record *s) { XFILE *f; char *server; char *type_str; unsigned type; char *comment; char line[1024]; const char *ptr; int count=0; f = x_fopen(s->fname,O_RDONLY, 0); if (!f) return; while (!x_feof(f)) { TALLOC_CTX *frame = NULL; if (!fgets_slash(line,sizeof(line),f)) continue; ptr = line; frame = talloc_stackframe(); if (!next_token_talloc(frame,&ptr,&server,NULL) || !next_token_talloc(frame,&ptr,&type_str,NULL) || !next_token_talloc(frame,&ptr,&comment,NULL)) { TALLOC_FREE(frame); continue; } sscanf(type_str, "%X", &type); complete_one(s, server, type, comment); count++; TALLOC_FREE(frame); } x_fclose(f); unlink(s->fname); DEBUG(2,("sync with %s(%s) for workgroup %s completed (%d records)\n", s->server, inet_ntoa(s->ip), s->workgroup, count)); }
static int collect_aliasmem(struct db_record *rec, void *priv) { struct aliasmem_state *state = (struct aliasmem_state *)priv; const char *p; char *alias_string; TALLOC_CTX *frame; if (strncmp((const char *)rec->key.dptr, MEMBEROF_PREFIX, MEMBEROF_PREFIX_LEN) != 0) return 0; p = (const char *)rec->value.dptr; frame = talloc_stackframe(); while (next_token_talloc(frame, &p, &alias_string, " ")) { struct dom_sid alias, member; const char *member_string; uint32_t num_sids; if (!string_to_sid(&alias, alias_string)) continue; if (dom_sid_compare(state->alias, &alias) != 0) continue; /* Ok, we found the alias we're looking for in the membership * list currently scanned. The key represents the alias * member. Add that. */ member_string = strchr((const char *)rec->key.dptr, '/'); /* Above we tested for MEMBEROF_PREFIX which includes the * slash. */ SMB_ASSERT(member_string != NULL); member_string += 1; if (!string_to_sid(&member, member_string)) continue; num_sids = *state->num; if (!NT_STATUS_IS_OK(add_sid_to_array(state->mem_ctx, &member, state->sids, &num_sids))) { /* talloc fail. */ break; } *state->num = num_sids; } TALLOC_FREE(frame); return 0; }
int main(int argc, const char *argv[]) { const char *config_file = get_dyn_CONFIGFILE(); const char *sequence = ""; poptContext pc; char *buff; TALLOC_CTX *ctx = talloc_stackframe(); struct poptOption long_options[] = { POPT_AUTOHELP POPT_COMMON_VERSION POPT_TABLEEND }; load_case_tables(); pc = poptGetContext(NULL, argc, argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "[OPTION...] <sequence-string>"); while(poptGetNextOpt(pc) != -1); setup_logging(poptGetArg(pc), true); sequence = poptGetArg(pc); if (sequence == NULL) { fprintf(stderr, "ERROR: missing sequence string\n"); return 1; } dbf = x_stderr; DEBUGLEVEL = 0; AllowDebugChange = false; if (!lp_load(config_file,false,true,false,true)) { fprintf(stderr,"Error loading services.\n"); return 1; } while(next_token_talloc(ctx, &sequence, &buff, NULL)) { printf("[%s]\n", buff); } talloc_free(ctx); return 0; }
static NTSTATUS one_alias_membership(const struct dom_sid *member, struct 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, " ")) { struct dom_sid alias; uint32_t num_sids; if (!string_to_sid(&alias, string_sid)) continue; num_sids = *num; status= add_sid_to_array_unique(NULL, &alias, sids, &num_sids); if (!NT_STATUS_IS_OK(status)) { goto done; } *num = num_sids; } done: TALLOC_FREE(frame); return status; }
/* upgrade one alias record from the old tdb format */ static int upgrade_alias_record(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, void *state) { const char *p = (const char *)data.dptr; char *string_sid; DOM_SID member; TALLOC_CTX *frame; if (strncmp((char *)key.dptr, MEMBEROF_PREFIX, MIN(key.dsize, strlen(MEMBEROF_PREFIX))) != 0) { return 0; } if (!string_to_sid(&member, strlen(MEMBEROF_PREFIX) + (const char *)key.dptr)) { DEBUG(0,("Bad alias key %s during upgrade\n", (const char *)key.dptr)); *(int *)state = -1; } frame = talloc_stackframe(); while (next_token_talloc(frame,&p, &string_sid, " ")) { DOM_SID alias; NTSTATUS status; string_to_sid(&alias, string_sid); status = add_aliasmem(&alias, &member); if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_ALIAS)) { DEBUG(0,("Ignoring orphaned alias record '%s'\n", string_sid)); } else if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to add alias member during upgrade - %s\n", nt_errstr(status))); *(int *)state = -1; TALLOC_FREE(frame); return -1; } } TALLOC_FREE(frame); return 0; }
static bool open_sockets_smbd(struct smbd_parent_context *parent, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, const char *smb_ports) { int num_interfaces = iface_count(); int i,j; const char **ports; unsigned dns_port = 0; #ifdef HAVE_ATEXIT atexit(killkids); #endif /* Stop zombies */ smbd_setup_sig_chld_handler(parent); ports = lp_smb_ports(); /* use a reasonable default set of ports - listing on 445 and 139 */ if (smb_ports) { char **l; l = str_list_make_v3(talloc_tos(), smb_ports, NULL); ports = discard_const_p(const char *, l); } for (j = 0; ports && ports[j]; j++) { unsigned port = atoi(ports[j]); if (port == 0 || port > 0xffff) { exit_server_cleanly("Invalid port in the config or on " "the commandline specified!"); } } if (lp_interfaces() && lp_bind_interfaces_only()) { /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_interfaces; i++) { const struct sockaddr_storage *ifss = iface_n_sockaddr_storage(i); if (ifss == NULL) { DEBUG(0,("open_sockets_smbd: " "interface %d has NULL IP address !\n", i)); continue; } for (j = 0; ports && ports[j]; j++) { unsigned port = atoi(ports[j]); /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } if (!smbd_open_one_socket(parent, ev_ctx, ifss, port)) { return false; } } } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ const char *sock_addr; char *sock_tok; const char *sock_ptr; #if HAVE_IPV6 sock_addr = "::,0.0.0.0"; #else sock_addr = "0.0.0.0"; #endif for (sock_ptr=sock_addr; next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) { for (j = 0; ports && ports[j]; j++) { struct sockaddr_storage ss; unsigned port = atoi(ports[j]); /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } /* open an incoming socket */ if (!interpret_string_addr(&ss, sock_tok, AI_NUMERICHOST|AI_PASSIVE)) { continue; } /* * If we fail to open any sockets * in this loop the parent-sockets == NULL * case below will prevent us from starting. */ (void)smbd_open_one_socket(parent, ev_ctx, &ss, port); } } } if (parent->sockets == NULL) { DEBUG(0,("open_sockets_smbd: No " "sockets available to bind to.\n")); return false; } /* Setup the main smbd so that we can get messages. Note that do this after starting listening. This is needed as when in clustered mode, ctdb won't allow us to start doing database operations until it has gone thru a full startup, which includes checking to see that smbd is listening. */ if (!serverid_register(messaging_server_id(msg_ctx), FLAG_MSG_GENERAL|FLAG_MSG_SMBD |FLAG_MSG_PRINT_GENERAL |FLAG_MSG_DBWRAP)) { DEBUG(0, ("open_sockets_smbd: Failed to register " "myself in serverid.tdb\n")); return false; } /* Listen to messages */ messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server); messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, smbd_parent_conf_updated); messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete); messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug); messaging_register(msg_ctx, NULL, MSG_SMB_BRL_VALIDATE, brl_revalidate); messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS, smb_parent_send_to_children); messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP, smb_parent_send_to_children); messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN, smb_tell_num_children); messaging_register(msg_ctx, NULL, ID_CACHE_DELETE, smbd_parent_id_cache_delete); messaging_register(msg_ctx, NULL, ID_CACHE_KILL, smbd_parent_id_cache_kill); if (lp_clustering()) { struct ctdbd_connection *conn = messaging_ctdbd_connection(); register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE, smbd_parent_ctdb_reconfigured, msg_ctx); register_with_ctdbd(conn, CTDB_SRVID_SAMBA_NOTIFY, smbd_parent_ctdb_reconfigured, msg_ctx); } #ifdef DEVELOPER messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT, msg_inject_fault); #endif if (lp_multicast_dns_register() && (dns_port != 0)) { #ifdef WITH_DNSSD_SUPPORT smbd_setup_mdns_registration(ev_ctx, parent, dns_port); #endif #ifdef WITH_AVAHI_SUPPORT void *avahi_conn; avahi_conn = avahi_start_register(ev_ctx, ev_ctx, dns_port); if (avahi_conn == NULL) { DEBUG(10, ("avahi_start_register failed\n")); } #endif } return true; }
static bool epmd_open_sockets(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { uint32_t num_ifs = iface_count(); uint16_t port; uint32_t i; if (lp_interfaces() && lp_bind_interfaces_only()) { /* * We have been given an interfaces line, and been told to only * bind to those interfaces. Create a socket per interface and * bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_ifs; i++) { const struct sockaddr_storage *ifss = iface_n_sockaddr_storage(i); port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx, msg_ctx, ndr_table_epmapper.syntax_id, ifss, 135); if (port == 0) { return false; } } } else { const char *sock_addr = lp_socket_address(); const char *sock_ptr; char *sock_tok; if (strequal(sock_addr, "0.0.0.0") || strequal(sock_addr, "::")) { #if HAVE_IPV6 sock_addr = "::"; #else sock_addr = "0.0.0.0"; #endif } for (sock_ptr = sock_addr; next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) { struct sockaddr_storage ss; /* open an incoming socket */ if (!interpret_string_addr(&ss, sock_tok, AI_NUMERICHOST|AI_PASSIVE)) { continue; } port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx, msg_ctx, ndr_table_epmapper.syntax_id, &ss, 135); if (port == 0) { return false; } } } return true; }
static bool open_sockets_smbd(struct smbd_parent_context *parent, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, const char *smb_ports) { int num_interfaces = iface_count(); int i; const char *ports; unsigned dns_port = 0; #ifdef HAVE_ATEXIT atexit(killkids); #endif /* Stop zombies */ smbd_setup_sig_chld_handler(ev_ctx); /* use a reasonable default set of ports - listing on 445 and 139 */ if (!smb_ports) { ports = lp_smb_ports(); if (!ports || !*ports) { ports = talloc_strdup(talloc_tos(), SMB_PORTS); } else { ports = talloc_strdup(talloc_tos(), ports); } } else { ports = talloc_strdup(talloc_tos(), smb_ports); } if (lp_interfaces() && lp_bind_interfaces_only()) { /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_interfaces; i++) { const struct sockaddr_storage *ifss = iface_n_sockaddr_storage(i); char *tok; const char *ptr; if (ifss == NULL) { DEBUG(0,("open_sockets_smbd: " "interface %d has NULL IP address !\n", i)); continue; } for (ptr=ports; next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) { unsigned port = atoi(tok); if (port == 0 || port > 0xffff) { continue; } /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } if (!smbd_open_one_socket(parent, ev_ctx, msg_ctx, ifss, port)) { return false; } } } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ char *tok; const char *ptr; const char *sock_addr = lp_socket_address(); char *sock_tok; const char *sock_ptr; if (strequal(sock_addr, "0.0.0.0") || strequal(sock_addr, "::")) { #if HAVE_IPV6 sock_addr = "::,0.0.0.0"; #else sock_addr = "0.0.0.0"; #endif } for (sock_ptr=sock_addr; next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) { for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) { struct sockaddr_storage ss; unsigned port = atoi(tok); if (port == 0 || port > 0xffff) { continue; } /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } /* open an incoming socket */ if (!interpret_string_addr(&ss, sock_tok, AI_NUMERICHOST|AI_PASSIVE)) { continue; } if (!smbd_open_one_socket(parent, ev_ctx, msg_ctx, &ss, port)) { return false; } } } } if (parent->sockets == NULL) { DEBUG(0,("open_sockets_smbd: No " "sockets available to bind to.\n")); return false; } /* Setup the main smbd so that we can get messages. Note that do this after starting listening. This is needed as when in clustered mode, ctdb won't allow us to start doing database operations until it has gone thru a full startup, which includes checking to see that smbd is listening. */ if (!serverid_register(procid_self(), FLAG_MSG_GENERAL|FLAG_MSG_SMBD |FLAG_MSG_PRINT_GENERAL |FLAG_MSG_DBWRAP)) { DEBUG(0, ("open_sockets_smbd: Failed to register " "myself in serverid.tdb\n")); return false; } /* Listen to messages */ messaging_register(msg_ctx, NULL, MSG_SMB_SAM_SYNC, msg_sam_sync); messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server); messaging_register(msg_ctx, NULL, MSG_SMB_FILE_RENAME, msg_file_was_renamed); messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, smb_conf_updated); messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete); messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug); messaging_register(msg_ctx, ev_ctx, MSG_PRINTER_PCAP, smb_pcap_updated); brl_register_msgs(msg_ctx); msg_idmap_register_msg(msg_ctx); #ifdef CLUSTER_SUPPORT if (lp_clustering()) { ctdbd_register_reconfigure(messaging_ctdbd_connection()); } #endif #ifdef DEVELOPER messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT, msg_inject_fault); #endif if (lp_multicast_dns_register() && (dns_port != 0)) { #ifdef WITH_DNSSD_SUPPORT smbd_setup_mdns_registration(ev_ctx, parent, dns_port); #endif #ifdef WITH_AVAHI_SUPPORT void *avahi_conn; avahi_conn = avahi_start_register(ev_ctx, ev_ctx, dns_port); if (avahi_conn == NULL) { DEBUG(10, ("avahi_start_register failed\n")); } #endif } return true; }
void announce_remote(time_t t) { char *s; const char *ptr; static time_t last_time = 0; char *s2; struct in_addr addr; char *comment; int stype = lp_default_server_announce(); TALLOC_CTX *frame = NULL; if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL))) return; last_time = t; s = lp_remote_announce(talloc_tos()); if (!*s) return; comment = string_truncate(lp_serverstring(talloc_tos()), MAX_SERVER_STRING_LENGTH); frame = talloc_stackframe(); for (ptr=s; next_token_talloc(frame,&ptr,&s2,NULL); ) { /* The entries are of the form a.b.c.d/WORKGROUP with WORKGROUP being optional */ const char *wgroup; char *pwgroup; int i; pwgroup = strchr_m(s2,'/'); if (pwgroup) *pwgroup++ = 0; if (!pwgroup || !*pwgroup) wgroup = lp_workgroup(); else wgroup = pwgroup; addr = interpret_addr2(s2); /* Announce all our names including aliases */ /* Give the ip address as the address of our first broadcast subnet. */ for(i=0; my_netbios_names(i); i++) { const char *name = my_netbios_names(i); DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n", name, inet_ntoa(addr) )); send_announcement(FIRST_SUBNET, ANN_HostAnnouncement, name, /* From nbt name. */ wgroup, 0x1d, /* To nbt name. */ addr, /* To ip. */ REMOTE_ANNOUNCE_INTERVAL, /* Time until next announce. */ name, /* Name to announce. */ stype, /* Type field. */ comment); } } TALLOC_FREE(frame); }
static bool wbinfo_lookuprids(const char *domain, const char *arg) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *dinfo = NULL; char *domain_name = NULL; const char **names = NULL; enum wbcSidType *types = NULL; size_t i; int num_rids; uint32 *rids = NULL; const char *p; char *ridstr; TALLOC_CTX *mem_ctx = NULL; bool ret = false; if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) { domain = get_winbind_domain(); } /* Send request */ wbc_status = wbcDomainInfo(domain, &dinfo); if (!WBC_ERROR_IS_OK(wbc_status)) { d_printf("wbcDomainInfo(%s) failed: %s\n", domain, wbcErrorString(wbc_status)); goto done; } mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { d_printf("talloc_new failed\n"); goto done; } num_rids = 0; rids = NULL; p = arg; while (next_token_talloc(mem_ctx, &p, &ridstr, " ,\n")) { uint32 rid = strtoul(ridstr, NULL, 10); ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids); } if (rids == NULL) { d_printf("no rids\n"); goto done; } wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids, (const char **)&domain_name, &names, &types); if (!WBC_ERROR_IS_OK(wbc_status)) { d_printf("winbind_lookup_rids failed: %s\n", wbcErrorString(wbc_status)); goto done; } d_printf("Domain: %s\n", domain_name); for (i=0; i<num_rids; i++) { d_printf("%8d: %s (%s)\n", rids[i], names[i], sid_type_lookup(types[i])); } ret = true; done: if (dinfo) { wbcFreeMemory(dinfo); } if (domain_name) { wbcFreeMemory(domain_name); } if (names) { wbcFreeMemory(names); } if (types) { wbcFreeMemory(types); } TALLOC_FREE(mem_ctx); return ret; }
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++) { uint32_t sa; uint32 g_access; uint32 s_access; DOM_SID sid; char *sidstr; enum security_ace_type type = SEC_ACE_TYPE_ACCESS_ALLOWED; if (!next_token_talloc(ctx, &pacl, &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); 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, SECURITY_DESCRIPTOR_REVISION_1, 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 NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, struct samu *sampass, const struct auth_usersupplied_info *user_info) { uint32 acct_ctrl = pdb_get_acct_ctrl(sampass); char *workstation_list; time_t kickoff_time; DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n",pdb_get_username(sampass))); /* Quit if the account was disabled. */ if (acct_ctrl & ACB_DISABLED) { DEBUG(1,("sam_account_ok: Account for user '%s' was disabled.\n", pdb_get_username(sampass))); return NT_STATUS_ACCOUNT_DISABLED; } /* Quit if the account was locked out. */ if (acct_ctrl & ACB_AUTOLOCK) { DEBUG(1,("sam_account_ok: Account for user %s was locked out.\n", pdb_get_username(sampass))); return NT_STATUS_ACCOUNT_LOCKED_OUT; } /* Quit if the account is not allowed to logon at this time. */ if (! logon_hours_ok(sampass)) { return NT_STATUS_INVALID_LOGON_HOURS; } /* Test account expire time */ kickoff_time = pdb_get_kickoff_time(sampass); if (kickoff_time != 0 && time(NULL) > kickoff_time) { DEBUG(1,("sam_account_ok: Account for user '%s' has expired.\n", pdb_get_username(sampass))); DEBUG(3,("sam_account_ok: Account expired at '%ld' unix time.\n", (long)kickoff_time)); return NT_STATUS_ACCOUNT_EXPIRED; } if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP) && !(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) { time_t must_change_time = pdb_get_pass_must_change_time(sampass); time_t last_set_time = pdb_get_pass_last_set_time(sampass); /* check for immediate expiry "must change at next logon" * for a user account. */ if (((acct_ctrl & (ACB_WSTRUST|ACB_SVRTRUST)) == 0) && (last_set_time == 0)) { DEBUG(1,("sam_account_ok: Account for user '%s' password must change!\n", pdb_get_username(sampass))); return NT_STATUS_PASSWORD_MUST_CHANGE; } /* check for expired password */ if (must_change_time < time(NULL) && must_change_time != 0) { DEBUG(1,("sam_account_ok: Account for user '%s' password expired!\n", pdb_get_username(sampass))); DEBUG(1,("sam_account_ok: Password expired at '%s' (%ld) unix time.\n", http_timestring(talloc_tos(), must_change_time), (long)must_change_time)); return NT_STATUS_PASSWORD_EXPIRED; } } /* Test workstation. Workstation list is comma separated. */ workstation_list = talloc_strdup(mem_ctx, pdb_get_workstations(sampass)); if (!workstation_list) return NT_STATUS_NO_MEMORY; if (*workstation_list) { bool invalid_ws = True; char *tok = NULL; const char *s = workstation_list; char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->workstation_name); if (machine_name == NULL) return NT_STATUS_NO_MEMORY; while (next_token_talloc(mem_ctx, &s, &tok, ",")) { DEBUG(10,("sam_account_ok: checking for workstation match %s and %s\n", tok, user_info->workstation_name)); if(strequal(tok, user_info->workstation_name)) { invalid_ws = False; break; } if (tok[0] == '+') { DEBUG(10,("sam_account_ok: checking for workstation %s in group: %s\n", machine_name, tok + 1)); if (user_in_group(machine_name, tok + 1)) { invalid_ws = False; break; } } TALLOC_FREE(tok); } TALLOC_FREE(tok); TALLOC_FREE(machine_name); if (invalid_ws) return NT_STATUS_INVALID_WORKSTATION; } if (acct_ctrl & ACB_DOMTRUST) { DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", pdb_get_username(sampass))); return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; } if (acct_ctrl & ACB_SVRTRUST) { if (!(user_info->logon_parameters & MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT)) { DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", pdb_get_username(sampass))); return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; } } if (acct_ctrl & ACB_WSTRUST) { if (!(user_info->logon_parameters & MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT)) { DEBUG(2,("sam_account_ok: Wksta trust account %s denied by server\n", pdb_get_username(sampass))); return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; } } return NT_STATUS_OK; }
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; }
bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, struct sockaddr_storage *pss) { char line[1024]; *pp_name = NULL; while(!x_feof(fp) && !x_ferror(fp)) { char *ip = NULL; char *flags = NULL; char *extra = NULL; char *name = NULL; const char *ptr; char *ptr1 = NULL; int count = 0; *name_type = -1; if (!fgets_slash(line,sizeof(line),fp)) { continue; } if (*line == '#') { continue; } ptr = line; if (next_token_talloc(ctx, &ptr, &ip, NULL)) ++count; if (next_token_talloc(ctx, &ptr, &name, NULL)) ++count; if (next_token_talloc(ctx, &ptr, &flags, NULL)) ++count; if (next_token_talloc(ctx, &ptr, &extra, NULL)) ++count; if (count <= 0) continue; if (count > 0 && count < 2) { DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n", line)); continue; } if (count >= 4) { DEBUG(0,("getlmhostsent: too many columns " "in lmhosts file (obsolete syntax)\n")); continue; } if (!flags) { flags = talloc_strdup(ctx, ""); if (!flags) { continue; } } DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); if (strchr_m(flags,'G') || strchr_m(flags,'S')) { DEBUG(0,("getlmhostsent: group flag " "in lmhosts ignored (obsolete)\n")); continue; } if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) { DEBUG(0,("getlmhostsent: invalid address " "%s.\n", ip)); } /* Extra feature. If the name ends in '#XX', * where XX is a hex number, then only add that name type. */ if((ptr1 = strchr_m(name, '#')) != NULL) { char *endptr; ptr1++; *name_type = (int)strtol(ptr1, &endptr, 16); if(!*ptr1 || (endptr == ptr1)) { DEBUG(0,("getlmhostsent: invalid name " "%s containing '#'.\n", name)); continue; } *(--ptr1) = '\0'; /* Truncate at the '#' */ } *pp_name = talloc_strdup(ctx, name); if (!*pp_name) { return false; } return true; } return false; }
static int do_global_checks(void) { int ret = 0; SMB_STRUCT_STAT st; const char *socket_options; if (lp_security() >= SEC_DOMAIN && !lp_encrypt_passwords()) { fprintf(stderr, "ERROR: in 'security=domain' mode the " "'encrypt passwords' parameter must always be " "set to 'true'.\n\n"); ret = 1; } if (lp_we_are_a_wins_server() && lp_wins_server_list()) { fprintf(stderr, "ERROR: both 'wins support = true' and " "'wins server = <server list>' cannot be set in " "the smb.conf file. nmbd will abort with this " "setting.\n\n"); ret = 1; } if (strequal(lp_workgroup(), lp_netbios_name())) { fprintf(stderr, "WARNING: 'workgroup' and 'netbios name' " "must differ.\n\n"); } if (!directory_exist_stat(lp_lock_directory(), &st)) { fprintf(stderr, "ERROR: lock directory %s does not exist\n\n", lp_lock_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: lock directory %s should have " "permissions 0755 for browsing to work\n\n", lp_lock_directory()); } if (!directory_exist_stat(lp_state_directory(), &st)) { fprintf(stderr, "ERROR: state directory %s does not exist\n\n", lp_state_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: state directory %s should have " "permissions 0755 for browsing to work\n\n", lp_state_directory()); } if (!directory_exist_stat(lp_cache_directory(), &st)) { fprintf(stderr, "ERROR: cache directory %s does not exist\n\n", lp_cache_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: cache directory %s should have " "permissions 0755 for browsing to work\n\n", lp_cache_directory()); } if (!directory_exist_stat(lp_pid_directory(), &st)) { fprintf(stderr, "ERROR: pid directory %s does not exist\n\n", lp_pid_directory()); ret = 1; } if (lp_passdb_expand_explicit()) { fprintf(stderr, "WARNING: passdb expand explicit = yes is " "deprecated\n\n"); } /* * Socket options. */ socket_options = lp_socket_options(); if (socket_options != NULL && (strstr(socket_options, "SO_SNDBUF") || strstr(socket_options, "SO_RCVBUF") || strstr(socket_options, "SO_SNDLOWAT") || strstr(socket_options, "SO_RCVLOWAT"))) { fprintf(stderr, "WARNING: socket options = %s\n" "This warning is printed because you set one of the\n" "following options: SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT,\n" "SO_RCVLOWAT\n" "Modern server operating systems are tuned for\n" "high network performance in the majority of situations;\n" "when you set 'socket options' you are overriding those\n" "settings.\n" "Linux in particular has an auto-tuning mechanism for\n" "buffer sizes (SO_SNDBUF, SO_RCVBUF) that will be\n" "disabled if you specify a socket buffer size. This can\n" "potentially cripple your TCP/IP stack.\n\n" "Getting the 'socket options' correct can make a big\n" "difference to your performance, but getting them wrong\n" "can degrade it by just as much. As with any other low\n" "level setting, if you must make changes to it, make\n " "small changes and test the effect before making any\n" "large changes.\n\n", socket_options); } /* * Password server sanity checks. */ if((lp_security() >= SEC_DOMAIN) && !*lp_password_server()) { const char *sec_setting; if(lp_security() == SEC_DOMAIN) sec_setting = "domain"; else if(lp_security() == SEC_ADS) sec_setting = "ads"; else sec_setting = ""; fprintf(stderr, "ERROR: The setting 'security=%s' requires the " "'password server' parameter be set to the " "default value * or a valid password server.\n\n", sec_setting ); ret = 1; } if((lp_security() >= SEC_DOMAIN) && (strcmp(lp_password_server(), "*") != 0)) { const char *sec_setting; if(lp_security() == SEC_DOMAIN) sec_setting = "domain"; else if(lp_security() == SEC_ADS) sec_setting = "ads"; else sec_setting = ""; fprintf(stderr, "WARNING: The setting 'security=%s' should NOT " "be combined with the 'password server' " "parameter.\n" "(by default Samba will discover the correct DC " "to contact automatically).\n\n", sec_setting ); } /* * Password chat sanity checks. */ if(lp_security() == SEC_USER && lp_unix_password_sync()) { /* * Check that we have a valid lp_passwd_program() if not using pam. */ #ifdef WITH_PAM if (!lp_pam_password_change()) { #endif if((lp_passwd_program(talloc_tos()) == NULL) || (strlen(lp_passwd_program(talloc_tos())) == 0)) { fprintf(stderr, "ERROR: the 'unix password sync' " "parameter is set and there is no valid " "'passwd program' parameter.\n\n"); ret = 1; } else { const char *passwd_prog; char *truncated_prog = NULL; const char *p; passwd_prog = lp_passwd_program(talloc_tos()); p = passwd_prog; next_token_talloc(talloc_tos(), &p, &truncated_prog, NULL); if (truncated_prog && access(truncated_prog, F_OK) == -1) { fprintf(stderr, "ERROR: the 'unix password sync' " "parameter is set and the " "'passwd program' (%s) cannot be " "executed (error was %s).\n\n", truncated_prog, strerror(errno)); ret = 1; } } #ifdef WITH_PAM } #endif if(lp_passwd_chat(talloc_tos()) == NULL) { fprintf(stderr, "ERROR: the 'unix password sync' parameter is " "set and there is no valid 'passwd chat' " "parameter.\n\n"); ret = 1; } if ((lp_passwd_program(talloc_tos()) != NULL) && (strlen(lp_passwd_program(talloc_tos())) > 0)) { /* check if there's a %u parameter present */ if(strstr_m(lp_passwd_program(talloc_tos()), "%u") == NULL) { fprintf(stderr, "ERROR: the 'passwd program' (%s) " "requires a '%%u' parameter.\n\n", lp_passwd_program(talloc_tos())); ret = 1; } } /* * Check that we have a valid script and that it hasn't * been written to expect the old password. */ if(lp_encrypt_passwords()) { if(strstr_m( lp_passwd_chat(talloc_tos()), "%o")!=NULL) { fprintf(stderr, "ERROR: the 'passwd chat' script [%s] " "expects to use the old plaintext " "password via the %%o substitution. With " "encrypted passwords this is not " "possible.\n\n", lp_passwd_chat(talloc_tos()) ); ret = 1; } } } if (strlen(lp_winbind_separator()) != 1) { fprintf(stderr, "ERROR: the 'winbind separator' parameter must " "be a single character.\n\n"); ret = 1; } if (*lp_winbind_separator() == '+') { fprintf(stderr, "'winbind separator = +' might cause problems " "with group membership.\n\n"); } if (lp_algorithmic_rid_base() < BASE_RID) { /* Try to prevent admin foot-shooting, we can't put algorithmic rids below 1000, that's the 'well known RIDs' on NT */ fprintf(stderr, "'algorithmic rid base' must be equal to or " "above %lu\n\n", BASE_RID); } if (lp_algorithmic_rid_base() & 1) { fprintf(stderr, "'algorithmic rid base' must be even.\n\n"); } #ifndef HAVE_DLOPEN if (lp_preload_modules()) { fprintf(stderr, "WARNING: 'preload modules = ' set while loading " "plugins not supported.\n\n"); } #endif if (!lp_passdb_backend()) { fprintf(stderr, "ERROR: passdb backend must have a value or be " "left out\n\n"); } if (lp_os_level() > 255) { fprintf(stderr, "WARNING: Maximum value for 'os level' is " "255!\n\n"); } if (strequal(lp_dos_charset(), "UTF8") || strequal(lp_dos_charset(), "UTF-8")) { fprintf(stderr, "ERROR: 'dos charset' must not be UTF8\n\n"); ret = 1; } return ret; }
static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) { struct cli_state *cli = NULL; char *desthost = NULL; struct sockaddr_storage dest_ss; const char *p; char *pserver = NULL; bool connected_ok = False; struct named_mutex *mutex = NULL; NTSTATUS status; pserver = talloc_strdup(mem_ctx, lp_passwordserver()); p = pserver; while(next_token_talloc(mem_ctx, &p, &desthost, LIST_SEP)) { desthost = talloc_sub_basic(mem_ctx, current_user_info.smb_name, current_user_info.domain, desthost); if (!desthost) { return NULL; } strupper_m(desthost); if (strequal(desthost, myhostname())) { DEBUG(1,("Password server loop - disabling " "password server %s\n", desthost)); continue; } if(!resolve_name( desthost, &dest_ss, 0x20, false)) { DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); continue; } if (ismyaddr((struct sockaddr *)(void *)&dest_ss)) { DEBUG(1,("Password server loop - disabling password server %s\n",desthost)); continue; } /* we use a mutex to prevent two connections at once - when a Win2k PDC get two connections where one hasn't completed a session setup yet it will send a TCP reset to the first connection (tridge) */ mutex = grab_named_mutex(talloc_tos(), desthost, 10); if (mutex == NULL) { return NULL; } status = cli_connect_nb(desthost, &dest_ss, 0, 0x20, lp_netbios_name(), Undefined, &cli); if (NT_STATUS_IS_OK(status)) { DEBUG(3,("connected to password server %s\n",desthost)); connected_ok = True; break; } DEBUG(10,("server_cryptkey: failed to connect to server %s. Error %s\n", desthost, nt_errstr(status) )); TALLOC_FREE(mutex); } if (!connected_ok) { DEBUG(0,("password server not available\n")); return NULL; } /* security = server just can't function with spnego */ cli->use_spnego = False; DEBUG(3,("got session\n")); status = cli_negprot(cli); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(mutex); DEBUG(1, ("%s rejected the negprot: %s\n", desthost, nt_errstr(status))); cli_shutdown(cli); return NULL; } if (cli->protocol < PROTOCOL_LANMAN2 || !(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { TALLOC_FREE(mutex); DEBUG(1,("%s isn't in user level security mode\n",desthost)); cli_shutdown(cli); return NULL; } /* Get the first session setup done quickly, to avoid silly Win2k bugs. (The next connection to the server will kill this one... */ status = cli_session_setup(cli, "", "", 0, "", 0, ""); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(mutex); DEBUG(0,("%s rejected the initial session setup (%s)\n", desthost, nt_errstr(status))); cli_shutdown(cli); return NULL; } TALLOC_FREE(mutex); DEBUG(3,("password server OK\n")); return cli; }
/** * Initialize a key in the registry: * create each component key of the specified path. */ static WERROR init_registry_key_internal(struct db_context *db, const char *add_path) { WERROR werr; TALLOC_CTX *frame = talloc_stackframe(); char *path = NULL; char *base = NULL; char *remaining = NULL; char *keyname; char *subkeyname; struct regsubkey_ctr *subkeys; const char *p, *p2; DEBUG(6, ("init_registry_key: Adding [%s]\n", add_path)); path = talloc_strdup(frame, add_path); base = talloc_strdup(frame, ""); if (!path || !base) { werr = WERR_NOMEM; goto fail; } p = path; while (next_token_talloc(frame, &p, &keyname, "\\")) { /* build up the registry path from the components */ if (*base) { base = talloc_asprintf(frame, "%s\\", base); if (!base) { werr = WERR_NOMEM; goto fail; } } base = talloc_asprintf_append(base, "%s", keyname); if (!base) { werr = WERR_NOMEM; goto fail; } /* get the immediate subkeyname (if we have one ) */ subkeyname = talloc_strdup(frame, ""); if (!subkeyname) { werr = WERR_NOMEM; goto fail; } if (*p) { remaining = talloc_strdup(frame, p); if (!remaining) { werr = WERR_NOMEM; goto fail; } p2 = remaining; if (!next_token_talloc(frame, &p2, &subkeyname, "\\")) { subkeyname = talloc_strdup(frame,p2); if (!subkeyname) { werr = WERR_NOMEM; goto fail; } } } DEBUG(10,("init_registry_key: Storing key [%s] with " "subkey [%s]\n", base, *subkeyname ? subkeyname : "NULL")); /* we don't really care if the lookup succeeds or not * since we are about to update the record. * We just want any subkeys already present */ werr = regsubkey_ctr_init(frame, &subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("talloc() failure!\n")); goto fail; } werr = regdb_fetch_keys_internal(db, base, subkeys); if (!W_ERROR_IS_OK(werr) && !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { goto fail; } if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { goto fail; } } if (!regdb_store_keys_internal(db, base, subkeys)) { werr = WERR_CAN_NOT_COMPLETE; goto fail; } } werr = WERR_OK; fail: TALLOC_FREE(frame); return werr; }