nsswitch/winbindd_sid.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003 
00004    Winbind daemon - sid related functions
00005 
00006    Copyright (C) Tim Potter 2000
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 #include "includes.h"
00024 #include "winbindd.h"
00025 
00026 #undef DBGC_CLASS
00027 #define DBGC_CLASS DBGC_WINBIND
00028 
00029 /* Convert a string  */
00030 
00031 static void lookupsid_recv(void *private_data, BOOL success,
00032                            const char *dom_name, const char *name,
00033                            enum lsa_SidType type);
00034 
00035 void winbindd_lookupsid(struct winbindd_cli_state *state)
00036 {
00037         DOM_SID sid;
00038 
00039         /* Ensure null termination */
00040         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
00041 
00042         DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid, 
00043                   state->request.data.sid));
00044 
00045         if (!string_to_sid(&sid, state->request.data.sid)) {
00046                 DEBUG(5, ("%s not a SID\n", state->request.data.sid));
00047                 request_error(state);
00048                 return;
00049         }
00050 
00051         winbindd_lookupsid_async(state->mem_ctx, &sid, lookupsid_recv, state);
00052 }
00053 
00054 static void lookupsid_recv(void *private_data, BOOL success,
00055                            const char *dom_name, const char *name,
00056                            enum lsa_SidType type)
00057 {
00058         struct winbindd_cli_state *state =
00059                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00060 
00061         if (!success) {
00062                 DEBUG(5, ("lookupsid returned an error\n"));
00063                 request_error(state);
00064                 return;
00065         }
00066 
00067         fstrcpy(state->response.data.name.dom_name, dom_name);
00068         fstrcpy(state->response.data.name.name, name);
00069         state->response.data.name.type = type;
00070         request_ok(state);
00071 }
00072 
00073 /**
00074  * Look up the SID for a qualified name.  
00075  **/
00076 
00077 static void lookupname_recv(void *private_data, BOOL success,
00078                             const DOM_SID *sid, enum lsa_SidType type);
00079 
00080 void winbindd_lookupname(struct winbindd_cli_state *state)
00081 {
00082         char *name_domain, *name_user;
00083         char *p;
00084 
00085         /* Ensure null termination */
00086         state->request.data.name.dom_name[sizeof(state->request.data.name.dom_name)-1]='\0';
00087 
00088         /* Ensure null termination */
00089         state->request.data.name.name[sizeof(state->request.data.name.name)-1]='\0';
00090 
00091         /* cope with the name being a fully qualified name */
00092         p = strstr(state->request.data.name.name, lp_winbind_separator());
00093         if (p) {
00094                 *p = 0;
00095                 name_domain = state->request.data.name.name;
00096                 name_user = p+1;
00097         } else {
00098                 name_domain = state->request.data.name.dom_name;
00099                 name_user = state->request.data.name.name;
00100         }
00101 
00102         DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
00103                   name_domain, lp_winbind_separator(), name_user));
00104 
00105         winbindd_lookupname_async(state->mem_ctx, name_domain, name_user,
00106                                   lookupname_recv, state);
00107 }
00108 
00109 static void lookupname_recv(void *private_data, BOOL success,
00110                             const DOM_SID *sid, enum lsa_SidType type)
00111 {
00112         struct winbindd_cli_state *state =
00113                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00114 
00115         if (!success) {
00116                 DEBUG(5, ("lookupname returned an error\n"));
00117                 request_error(state);
00118                 return;
00119         }
00120 
00121         sid_to_string(state->response.data.sid.sid, sid);
00122         state->response.data.sid.type = type;
00123         request_ok(state);
00124         return;
00125 }
00126 
00127 void winbindd_lookuprids(struct winbindd_cli_state *state)
00128 {
00129         struct winbindd_domain *domain;
00130         DOM_SID domain_sid;
00131         
00132         /* Ensure null termination */
00133         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
00134 
00135         DEBUG(10, ("lookup_rids: %s\n", state->request.data.sid));
00136 
00137         if (!string_to_sid(&domain_sid, state->request.data.sid)) {
00138                 DEBUG(5, ("Could not convert %s to SID\n",
00139                           state->request.data.sid));
00140                 request_error(state);
00141                 return;
00142         }
00143 
00144         domain = find_lookup_domain_from_sid(&domain_sid);
00145         if (domain == NULL) {
00146                 DEBUG(10, ("Could not find domain for name %s\n",
00147                            state->request.domain_name));
00148                 request_error(state);
00149                 return;
00150         }
00151 
00152         sendto_domain(state, domain);
00153 }
00154 
00155 static struct winbindd_child static_idmap_child;
00156 
00157 void init_idmap_child(void)
00158 {
00159         setup_domain_child(NULL, &static_idmap_child, "idmap");
00160 }
00161 
00162 struct winbindd_child *idmap_child(void)
00163 {
00164         return &static_idmap_child;
00165 }
00166 
00167 /* Convert a sid to a uid.  We assume we only have one rid attached to the
00168    sid. */
00169 
00170 static void sid2uid_recv(void *private_data, BOOL success, uid_t uid)
00171 {
00172         struct winbindd_cli_state *state =
00173                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00174 
00175         if (!success) {
00176                 DEBUG(5, ("Could not convert sid %s\n",
00177                           state->request.data.sid));
00178                 request_error(state);
00179                 return;
00180         }
00181 
00182         state->response.data.uid = uid;
00183         request_ok(state);
00184 }
00185 
00186 static void sid2uid_lookupsid_recv( void *private_data, BOOL success, 
00187                                     const char *domain_name, 
00188                                     const char *name, 
00189                                     enum lsa_SidType type)
00190 {
00191         struct winbindd_cli_state *state =
00192                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00193         DOM_SID sid;
00194 
00195         if (!success) {
00196                 DEBUG(5, ("sid2uid_lookupsid_recv Could not convert get sid type for %s\n",
00197                           state->request.data.sid));
00198                 request_error(state);
00199                 return;
00200         }
00201 
00202         if ( (type!=SID_NAME_USER) && (type!=SID_NAME_COMPUTER) ) {
00203                 DEBUG(5,("sid2uid_lookupsid_recv: Sid %s is not a user or a computer.\n", 
00204                          state->request.data.sid));
00205                 request_error(state);
00206                 return;         
00207         }
00208 
00209         if (!string_to_sid(&sid, state->request.data.sid)) {
00210                 DEBUG(1, ("sid2uid_lookupsid_recv: Could not get convert sid %s from string\n",
00211                           state->request.data.sid));
00212                 request_error(state);
00213                 return;
00214         }
00215         
00216         /* always use the async interface (may block) */
00217         winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state);
00218 }
00219 
00220 void winbindd_sid_to_uid(struct winbindd_cli_state *state)
00221 {
00222         DOM_SID sid;
00223 
00224         /* Ensure null termination */
00225         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
00226 
00227         DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
00228                   state->request.data.sid));
00229 
00230         if (!string_to_sid(&sid, state->request.data.sid)) {
00231                 DEBUG(1, ("Could not get convert sid %s from string\n",
00232                           state->request.data.sid));
00233                 request_error(state);
00234                 return;
00235         }
00236 
00237         /* Validate the SID as a user.  Hopefully this will hit cache.
00238            Needed to prevent DoS by exhausting the uid allocation
00239            range from random SIDs. */
00240 
00241         winbindd_lookupsid_async( state->mem_ctx, &sid, sid2uid_lookupsid_recv, state );
00242 }
00243 
00244 /* Convert a sid to a gid.  We assume we only have one rid attached to the
00245    sid.*/
00246 
00247 static void sid2gid_recv(void *private_data, BOOL success, gid_t gid)
00248 {
00249         struct winbindd_cli_state *state =
00250                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00251 
00252         if (!success) {
00253                 DEBUG(5, ("Could not convert sid %s\n",
00254                           state->request.data.sid));
00255                 request_error(state);
00256                 return;
00257         }
00258 
00259         state->response.data.gid = gid;
00260         request_ok(state);
00261 }
00262 
00263 static void sid2gid_lookupsid_recv( void *private_data, BOOL success, 
00264                                     const char *domain_name, 
00265                                     const char *name, 
00266                                     enum lsa_SidType type)
00267 {
00268         struct winbindd_cli_state *state =
00269                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00270         DOM_SID sid;
00271 
00272         if (!success) {
00273                 DEBUG(5, ("sid2gid_lookupsid_recv: Could not convert get sid type for %s\n",
00274                           state->request.data.sid));
00275                 request_error(state);
00276                 return;
00277         }
00278 
00279         if ( (type!=SID_NAME_DOM_GRP) &&
00280              (type!=SID_NAME_ALIAS) && 
00281              (type!=SID_NAME_WKN_GRP) ) 
00282         {
00283                 DEBUG(5,("sid2gid_lookupsid_recv: Sid %s is not a group.\n", 
00284                          state->request.data.sid));
00285                 request_error(state);
00286                 return;         
00287         }
00288 
00289         if (!string_to_sid(&sid, state->request.data.sid)) {
00290                 DEBUG(1, ("sid2gid_lookupsid_recv: Could not get convert sid %s from string\n",
00291                           state->request.data.sid));
00292                 request_error(state);
00293                 return;
00294         }
00295         
00296         /* always use the async interface (may block) */
00297         winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state);
00298 }
00299 
00300 void winbindd_sid_to_gid(struct winbindd_cli_state *state)
00301 {
00302         DOM_SID sid;
00303 
00304         /* Ensure null termination */
00305         state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
00306 
00307         DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,
00308                   state->request.data.sid));
00309 
00310         if (!string_to_sid(&sid, state->request.data.sid)) {
00311                 DEBUG(1, ("Could not get convert sid %s from string\n",
00312                           state->request.data.sid));
00313                 request_error(state);
00314                 return;
00315         }
00316 
00317         /* Validate the SID as a group.  Hopefully this will hit cache.
00318            Needed to prevent DoS by exhausting the uid allocation
00319            range from random SIDs. */
00320 
00321         winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv, state );        
00322 }
00323 
00324 static void sids2xids_recv(void *private_data, BOOL success, void *data, int len)
00325 {
00326         struct winbindd_cli_state *state =
00327                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00328 
00329         if (!success) {
00330                 DEBUG(5, ("Could not convert sids to xids\n"));
00331                 request_error(state);
00332                 return;
00333         }
00334 
00335         state->response.extra_data.data = data;
00336         state->response.length = sizeof(state->response) + len;
00337         request_ok(state);
00338 }
00339 
00340 void winbindd_sids_to_unixids(struct winbindd_cli_state *state)
00341 {
00342         DEBUG(3, ("[%5lu]: sids to xids\n", (unsigned long)state->pid));
00343 
00344         winbindd_sids2xids_async(state->mem_ctx,
00345                         state->request.extra_data.data,
00346                         state->request.extra_len,
00347                         sids2xids_recv, state);
00348 }
00349 
00350 static void set_mapping_recv(void *private_data, BOOL success)
00351 {
00352         struct winbindd_cli_state *state =
00353                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00354 
00355         if (!success) {
00356                 DEBUG(5, ("Could not set sid mapping\n"));
00357                 request_error(state);
00358                 return;
00359         }
00360 
00361         request_ok(state);
00362 }
00363 
00364 void winbindd_set_mapping(struct winbindd_cli_state *state)
00365 {
00366         struct id_map map;
00367         DOM_SID sid;
00368 
00369         DEBUG(3, ("[%5lu]: set id map\n", (unsigned long)state->pid));
00370 
00371         if ( ! state->privileged) {
00372                 DEBUG(0, ("Only root is allowed to set mappings!\n"));
00373                 request_error(state);
00374                 return;
00375         }
00376 
00377         if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid)) {
00378                 DEBUG(1, ("Could not get convert sid %s from string\n",
00379                           state->request.data.sid));
00380                 request_error(state);
00381                 return;
00382         }
00383 
00384         map.sid = &sid;
00385         map.xid.id = state->request.data.dual_idmapset.id;
00386         map.xid.type = state->request.data.dual_idmapset.type;
00387 
00388         winbindd_set_mapping_async(state->mem_ctx, &map,
00389                         set_mapping_recv, state);
00390 }
00391 
00392 static void set_hwm_recv(void *private_data, BOOL success)
00393 {
00394         struct winbindd_cli_state *state =
00395                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00396 
00397         if (!success) {
00398                 DEBUG(5, ("Could not set sid mapping\n"));
00399                 request_error(state);
00400                 return;
00401         }
00402 
00403         request_ok(state);
00404 }
00405 
00406 void winbindd_set_hwm(struct winbindd_cli_state *state)
00407 {
00408         struct unixid xid;
00409 
00410         DEBUG(3, ("[%5lu]: set hwm\n", (unsigned long)state->pid));
00411 
00412         if ( ! state->privileged) {
00413                 DEBUG(0, ("Only root is allowed to set mappings!\n"));
00414                 request_error(state);
00415                 return;
00416         }
00417 
00418         xid.id = state->request.data.dual_idmapset.id;
00419         xid.type = state->request.data.dual_idmapset.type;
00420 
00421         winbindd_set_hwm_async(state->mem_ctx, &xid, set_hwm_recv, state);
00422 }
00423 
00424 /* Convert a uid to a sid */
00425 
00426 static void uid2sid_recv(void *private_data, BOOL success, const char *sid)
00427 {
00428         struct winbindd_cli_state *state =
00429                 (struct winbindd_cli_state *)private_data;
00430 
00431         if (success) {
00432                 DEBUG(10,("uid2sid: uid %lu has sid %s\n",
00433                           (unsigned long)(state->request.data.uid), sid));
00434                 fstrcpy(state->response.data.sid.sid, sid);
00435                 state->response.data.sid.type = SID_NAME_USER;
00436                 request_ok(state);
00437                 return;
00438         }
00439 
00440         request_error(state);
00441         return;
00442 }
00443 
00444 void winbindd_uid_to_sid(struct winbindd_cli_state *state)
00445 {
00446         DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid, 
00447                   (unsigned long)state->request.data.uid));
00448 
00449         /* always go via the async interface (may block) */
00450         winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, uid2sid_recv, state);
00451 }
00452 
00453 /* Convert a gid to a sid */
00454 
00455 static void gid2sid_recv(void *private_data, BOOL success, const char *sid)
00456 {
00457         struct winbindd_cli_state *state =
00458                 (struct winbindd_cli_state *)private_data;
00459 
00460         if (success) {
00461                 DEBUG(10,("gid2sid: gid %lu has sid %s\n",
00462                           (unsigned long)(state->request.data.gid), sid));
00463                 fstrcpy(state->response.data.sid.sid, sid);
00464                 state->response.data.sid.type = SID_NAME_DOM_GRP;
00465                 request_ok(state);
00466                 return;
00467         }
00468 
00469         request_error(state);
00470         return;
00471 }
00472 
00473 
00474 void winbindd_gid_to_sid(struct winbindd_cli_state *state)
00475 {
00476         DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid, 
00477                   (unsigned long)state->request.data.gid));
00478 
00479         /* always use async calls (may block) */
00480         winbindd_gid2sid_async(state->mem_ctx, state->request.data.gid, gid2sid_recv, state);
00481 }
00482 
00483 void winbindd_allocate_uid(struct winbindd_cli_state *state)
00484 {
00485         if ( !state->privileged ) {
00486                 DEBUG(2, ("winbindd_allocate_uid: non-privileged access "
00487                           "denied!\n"));
00488                 request_error(state);
00489                 return;
00490         }
00491 
00492         sendto_child(state, idmap_child());
00493 }
00494 
00495 enum winbindd_result winbindd_dual_allocate_uid(struct winbindd_domain *domain,
00496                                                 struct winbindd_cli_state *state)
00497 {
00498         struct unixid xid;
00499 
00500         if (!NT_STATUS_IS_OK(idmap_allocate_uid(&xid))) {
00501                 return WINBINDD_ERROR;
00502         }
00503         state->response.data.uid = xid.id;
00504         return WINBINDD_OK;
00505 }
00506 
00507 void winbindd_allocate_gid(struct winbindd_cli_state *state)
00508 {
00509         if ( !state->privileged ) {
00510                 DEBUG(2, ("winbindd_allocate_gid: non-privileged access "
00511                           "denied!\n"));
00512                 request_error(state);
00513                 return;
00514         }
00515 
00516         sendto_child(state, idmap_child());
00517 }
00518 
00519 enum winbindd_result winbindd_dual_allocate_gid(struct winbindd_domain *domain,
00520                                                 struct winbindd_cli_state *state)
00521 {
00522         struct unixid xid;
00523 
00524         if (!NT_STATUS_IS_OK(idmap_allocate_gid(&xid))) {
00525                 return WINBINDD_ERROR;
00526         }
00527         state->response.data.gid = xid.id;
00528         return WINBINDD_OK;
00529 }
00530 
00531 static void dump_maps_recv(void *private_data, BOOL success)
00532 {
00533         struct winbindd_cli_state *state =
00534                 talloc_get_type_abort(private_data, struct winbindd_cli_state);
00535 
00536         if (!success) {
00537                 DEBUG(5, ("Could not dump maps\n"));
00538                 request_error(state);
00539                 return;
00540         }
00541 
00542         request_ok(state);
00543 }
00544 
00545 void winbindd_dump_maps(struct winbindd_cli_state *state)
00546 {
00547         if ( ! state->privileged) {
00548                 DEBUG(0, ("Only root is allowed to ask for an idmap dump!\n"));
00549                 request_error(state);
00550                 return;
00551         }
00552 
00553         DEBUG(3, ("[%5lu]: dump maps\n", (unsigned long)state->pid));
00554 
00555         winbindd_dump_maps_async(state->mem_ctx,
00556                         state->request.extra_data.data,
00557                         state->request.extra_len,
00558                         dump_maps_recv, state);
00559 }
00560 

Sambaに対してSat Aug 29 21:23:11 2009に生成されました。  doxygen 1.4.7