Changeset 232 for branches/samba-3.2.x/source/winbindd/winbindd_dual.c
- Timestamp:
- May 27, 2009, 9:09:42 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.2.x/source/winbindd/winbindd_dual.c
r228 r232 881 881 { 882 882 struct winbindd_domain *domain; 883 struct winbindd_domain *primary_domain = NULL; 883 884 const char *domainname = (const char *)data->data; 884 885 … … 893 894 return; 894 895 } 896 897 primary_domain = find_our_domain(); 895 898 896 899 /* Mark the requested domain offline. */ … … 903 906 DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name)); 904 907 set_domain_offline(domain); 908 /* we are in the trusted domain, set the primary domain 909 * offline too */ 910 if (domain != primary_domain) { 911 set_domain_offline(primary_domain); 912 } 905 913 } 906 914 } … … 916 924 { 917 925 struct winbindd_domain *domain; 926 struct winbindd_domain *primary_domain = NULL; 918 927 const char *domainname = (const char *)data->data; 919 928 … … 928 937 return; 929 938 } 939 940 primary_domain = find_our_domain(); 930 941 931 942 /* Set our global state as online. */ … … 943 954 winbindd_flush_negative_conn_cache(domain); 944 955 set_domain_online_request(domain); 956 957 /* we can be in trusted domain, which will contact primary domain 958 * we have to bring primary domain online in trusted domain process 959 * see, winbindd_dual_pam_auth() --> winbindd_dual_pam_auth_samlogon() 960 * --> contact_domain = find_our_domain() 961 * */ 962 if (domain != primary_domain) { 963 winbindd_flush_negative_conn_cache(primary_domain); 964 set_domain_online_request(primary_domain); 965 } 945 966 } 946 967 } … … 1020 1041 } 1021 1042 1022 1023 static bool fork_domain_child(struct winbindd_child *child) 1024 { 1025 int fdpair[2]; 1026 struct winbindd_cli_state state; 1043 void ccache_remove_all_after_fork(void); 1044 1045 bool winbindd_reinit_after_fork(const char *logfilename) 1046 { 1027 1047 struct winbindd_domain *domain; 1028 struct winbindd_domain *primary_domain = NULL; 1029 1030 if (child->domain) { 1031 DEBUG(10, ("fork_domain_child called for domain '%s'\n", 1032 child->domain->name)); 1033 } else { 1034 DEBUG(10, ("fork_domain_child called without domain.\n")); 1035 } 1036 1037 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) { 1038 DEBUG(0, ("Could not open child pipe: %s\n", 1039 strerror(errno))); 1040 return False; 1041 } 1042 1043 ZERO_STRUCT(state); 1044 state.pid = sys_getpid(); 1045 1046 child->pid = sys_fork(); 1047 1048 if (child->pid == -1) { 1049 DEBUG(0, ("Could not fork: %s\n", strerror(errno))); 1050 return False; 1051 } 1052 1053 if (child->pid != 0) { 1054 /* Parent */ 1055 close(fdpair[0]); 1056 child->next = child->prev = NULL; 1057 DLIST_ADD(children, child); 1058 child->event.fd = fdpair[1]; 1059 child->event.flags = 0; 1060 child->requests = NULL; 1061 add_fd_event(&child->event); 1062 return True; 1063 } 1064 1065 /* Child */ 1066 1067 /* Stop zombies in children */ 1068 CatchChild(); 1069 1070 state.sock = fdpair[0]; 1071 close(fdpair[1]); 1072 1073 if (!reinit_after_fork(winbind_messaging_context(), true)) { 1048 struct winbindd_child *cl; 1049 1050 if (!reinit_after_fork(winbind_messaging_context(), 1051 winbind_event_context(), true)) { 1074 1052 DEBUG(0,("reinit_after_fork() failed\n")); 1075 _exit(0);1053 return false; 1076 1054 } 1077 1055 1078 1056 close_conns_after_fork(); 1079 1057 1080 if (!override_logfile ) {1081 lp_set_logfile( child->logfilename);1058 if (!override_logfile && logfilename) { 1059 lp_set_logfile(logfilename); 1082 1060 reopen_logs(); 1083 1061 } 1084 1085 /*1086 * For clustering, we need to re-init our ctdbd connection after the1087 * fork1088 */1089 if (!NT_STATUS_IS_OK(messaging_reinit(winbind_messaging_context())))1090 exit(1);1091 1062 1092 1063 /* Don't handle the same messages as our parent. */ … … 1108 1079 MSG_DEBUG, NULL); 1109 1080 1110 /* Handle online/offline messages. */ 1111 messaging_register(winbind_messaging_context(), NULL, 1112 MSG_WINBIND_OFFLINE, child_msg_offline); 1113 messaging_register(winbind_messaging_context(), NULL, 1114 MSG_WINBIND_ONLINE, child_msg_online); 1115 messaging_register(winbind_messaging_context(), NULL, 1116 MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus); 1117 messaging_register(winbind_messaging_context(), NULL, 1118 MSG_DUMP_EVENT_LIST, child_msg_dump_event_list); 1119 messaging_register(winbind_messaging_context(), NULL, 1120 MSG_DEBUG, debug_message); 1121 1081 /* We have destroyed all events in the winbindd_event_context 1082 * in reinit_after_fork(), so clean out all possible pending 1083 * event pointers. */ 1084 1085 /* Deal with check_online_events. */ 1086 1087 for (domain = domain_list(); domain; domain = domain->next) { 1088 TALLOC_FREE(domain->check_online_event); 1089 } 1090 1091 /* Ensure we're not handling a credential cache event inherited 1092 * from our parent. */ 1093 1094 ccache_remove_all_after_fork(); 1095 1096 /* Destroy all possible events in child list. */ 1097 for (cl = children; cl != NULL; cl = cl->next) { 1098 struct winbindd_async_request *request; 1099 1100 for (request = cl->requests; request; request = request->next) { 1101 TALLOC_FREE(request->reply_timeout_event); 1102 } 1103 TALLOC_FREE(cl->lockout_policy_event); 1104 1105 /* Children should never be able to send 1106 * each other messages, all messages must 1107 * go through the parent. 1108 */ 1109 cl->pid = (pid_t)0; 1110 } 1111 /* 1112 * This is a little tricky, children must not 1113 * send an MSG_WINBIND_ONLINE message to idmap_child(). 1114 * If we are in a child of our primary domain or 1115 * in the process created by fork_child_dc_connect(), 1116 * and the primary domain cannot go online, 1117 * fork_child_dc_connection() sends MSG_WINBIND_ONLINE 1118 * periodically to idmap_child(). 1119 * 1120 * The sequence is, fork_child_dc_connect() ---> getdcs() ---> 1121 * get_dc_name_via_netlogon() ---> cm_connect_netlogon() 1122 * ---> init_dc_connection() ---> cm_open_connection ---> 1123 * set_domain_online(), sends MSG_WINBIND_ONLINE to 1124 * idmap_child(). Disallow children sending messages 1125 * to each other, all messages must go through the parent. 1126 */ 1127 cl = idmap_child(); 1128 cl->pid = (pid_t)0; 1129 1130 return true; 1131 } 1132 1133 static bool fork_domain_child(struct winbindd_child *child) 1134 { 1135 int fdpair[2]; 1136 struct winbindd_cli_state state; 1137 struct winbindd_domain *primary_domain = NULL; 1138 1139 if (child->domain) { 1140 DEBUG(10, ("fork_domain_child called for domain '%s'\n", 1141 child->domain->name)); 1142 } else { 1143 DEBUG(10, ("fork_domain_child called without domain.\n")); 1144 } 1145 1146 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) { 1147 DEBUG(0, ("Could not open child pipe: %s\n", 1148 strerror(errno))); 1149 return False; 1150 } 1151 1152 ZERO_STRUCT(state); 1153 state.pid = sys_getpid(); 1154 1155 child->pid = sys_fork(); 1156 1157 if (child->pid == -1) { 1158 DEBUG(0, ("Could not fork: %s\n", strerror(errno))); 1159 return False; 1160 } 1161 1162 if (child->pid != 0) { 1163 /* Parent */ 1164 close(fdpair[0]); 1165 child->next = child->prev = NULL; 1166 DLIST_ADD(children, child); 1167 child->event.fd = fdpair[1]; 1168 child->event.flags = 0; 1169 add_fd_event(&child->event); 1170 return True; 1171 } 1172 1173 /* Child */ 1174 1175 /* Stop zombies in children */ 1176 CatchChild(); 1177 1178 state.sock = fdpair[0]; 1179 close(fdpair[1]); 1180 1181 if (!winbindd_reinit_after_fork(child->logfilename)) { 1182 DEBUG(0, ("winbindd_reinit_after_fork failed.\n")); 1183 _exit(0); 1184 } 1185 1186 /* Handle online/offline messages. */ 1187 messaging_register(winbind_messaging_context(), NULL, 1188 MSG_WINBIND_OFFLINE, child_msg_offline); 1189 messaging_register(winbind_messaging_context(), NULL, 1190 MSG_WINBIND_ONLINE, child_msg_online); 1191 messaging_register(winbind_messaging_context(), NULL, 1192 MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus); 1193 messaging_register(winbind_messaging_context(), NULL, 1194 MSG_DUMP_EVENT_LIST, child_msg_dump_event_list); 1195 messaging_register(winbind_messaging_context(), NULL, 1196 MSG_DEBUG, debug_message); 1197 1198 primary_domain = find_our_domain(); 1199 1200 if (primary_domain == NULL) { 1201 smb_panic("no primary domain found"); 1202 } 1203 1204 /* It doesn't matter if we allow cache login, 1205 * try to bring domain online after fork. */ 1122 1206 if ( child->domain ) { 1123 1207 child->domain->startup = True; 1124 1208 child->domain->startup_time = time(NULL); 1125 } 1126 1127 /* Ensure we have no pending check_online events other 1128 than one for this domain or the primary domain. */ 1129 1130 for (domain = domain_list(); domain; domain = domain->next) { 1131 if (domain->primary) { 1132 primary_domain = domain; 1133 } 1134 if ((domain != child->domain) && !domain->primary) { 1135 TALLOC_FREE(domain->check_online_event); 1136 } 1137 } 1138 1139 /* Ensure we're not handling an event inherited from 1140 our parent. */ 1141 1142 cancel_named_event(winbind_event_context(), 1143 "krb5_ticket_refresh_handler"); 1209 /* we can be in primary domain or in trusted domain 1210 * If we are in trusted domain, set the primary domain 1211 * in start-up mode */ 1212 if (!(child->domain->internal)) { 1213 set_domain_online_request(child->domain); 1214 if (!(child->domain->primary)) { 1215 primary_domain->startup = True; 1216 primary_domain->startup_time = time(NULL); 1217 set_domain_online_request(primary_domain); 1218 } 1219 } 1220 } 1221 1222 /* 1223 * We are in idmap child, make sure that we set the 1224 * check_online_event to bring primary domain online. 1225 */ 1226 if (child == idmap_child()) { 1227 set_domain_online_request(primary_domain); 1228 } 1144 1229 1145 1230 /* We might be in the idmap child...*/ … … 1225 1310 TALLOC_FREE(frame); 1226 1311 perror("select"); 1227 return False;1312 _exit(1); 1228 1313 } 1229 1314 … … 1233 1318 if (state.finished) { 1234 1319 /* we lost contact with our parent */ 1235 exit(0);1320 _exit(0); 1236 1321 } 1237 1322
Note:
See TracChangeset
for help on using the changeset viewer.