rpc_server/srv_dfs_nt.c

説明を見る。
00001 /* 
00002  *  Unix SMB/CIFS implementation.
00003  *  RPC Pipe client / server routines for Dfs
00004  *  Copyright (C) Shirish Kalele        2000.
00005  *  Copyright (C) Jeremy Allison        2001.
00006  *  Copyright (C) Jelmer Vernooij       2005.
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 /* This is the implementation of the dfs pipe. */
00024 
00025 #include "includes.h"
00026 
00027 #undef DBGC_CLASS
00028 #define DBGC_CLASS DBGC_MSDFS
00029 
00030 /* This function does not return a WERROR or NTSTATUS code but rather 1 if
00031    dfs exists, or 0 otherwise. */
00032 
00033 uint32 _dfs_GetManagerVersion(pipes_struct *p, NETDFS_Q_DFS_GETMANAGERVERSION *q_u, NETDFS_R_DFS_GETMANAGERVERSION *r_u)
00034 {
00035         if(lp_host_msdfs()) 
00036                 return 1;
00037         else
00038                 return 0;
00039 }
00040 
00041 WERROR _dfs_Add(pipes_struct *p, NETDFS_Q_DFS_ADD* q_u, NETDFS_R_DFS_ADD *r_u)
00042 {
00043         struct current_user user;
00044         struct junction_map jn;
00045         struct referral* old_referral_list = NULL;
00046         BOOL self_ref = False;
00047         int consumedcnt = 0;
00048         BOOL exists = False;
00049 
00050         pstring dfspath, servername, sharename;
00051         pstring altpath;
00052 
00053         get_current_user(&user,p);
00054 
00055         if (user.ut.uid != 0) {
00056                 DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
00057                 return WERR_ACCESS_DENIED;
00058         }
00059 
00060         unistr2_to_ascii(dfspath, &q_u->path, sizeof(dfspath)-1);
00061         unistr2_to_ascii(servername, &q_u->server, sizeof(servername)-1);
00062         unistr2_to_ascii(sharename, &q_u->share, sizeof(sharename)-1);
00063 
00064         DEBUG(5,("init_reply_dfs_add: Request to add %s -> %s\\%s.\n",
00065                 dfspath, servername, sharename));
00066 
00067         pstrcpy(altpath, servername);
00068         pstrcat(altpath, "\\");
00069         pstrcat(altpath, sharename);
00070 
00071         /* The following call can change the cwd. */
00072         if(NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, dfspath, &jn, &consumedcnt, &self_ref))) {
00073                 exists = True;
00074                 jn.referral_count += 1;
00075                 old_referral_list = jn.referral_list;
00076         } else {
00077                 jn.referral_count = 1;
00078         }
00079 
00080         vfs_ChDir(p->conn,p->conn->connectpath);
00081 
00082         jn.referral_list = TALLOC_ARRAY(p->mem_ctx, struct referral, jn.referral_count);
00083         if(jn.referral_list == NULL) {
00084                 DEBUG(0,("init_reply_dfs_add: talloc failed for referral list!\n"));
00085                 return WERR_DFS_INTERNAL_ERROR;
00086         }
00087 
00088         if(old_referral_list) {
00089                 memcpy(jn.referral_list, old_referral_list, sizeof(struct referral)*jn.referral_count-1);
00090         }
00091   
00092         jn.referral_list[jn.referral_count-1].proximity = 0;
00093         jn.referral_list[jn.referral_count-1].ttl = REFERRAL_TTL;
00094 
00095         pstrcpy(jn.referral_list[jn.referral_count-1].alternate_path, altpath);
00096   
00097         if(!create_msdfs_link(&jn, exists)) {
00098                 vfs_ChDir(p->conn,p->conn->connectpath);
00099                 return WERR_DFS_CANT_CREATE_JUNCT;
00100         }
00101         vfs_ChDir(p->conn,p->conn->connectpath);
00102 
00103         return WERR_OK;
00104 }
00105 
00106 WERROR _dfs_Remove(pipes_struct *p, NETDFS_Q_DFS_REMOVE *q_u, 
00107                    NETDFS_R_DFS_REMOVE *r_u)
00108 {
00109         struct current_user user;
00110         struct junction_map jn;
00111         BOOL self_ref = False;
00112         int consumedcnt = 0;
00113         BOOL found = False;
00114 
00115         pstring dfspath, servername, sharename;
00116         pstring altpath;
00117 
00118         get_current_user(&user,p);
00119 
00120         if (user.ut.uid != 0) {
00121                 DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
00122                 return WERR_ACCESS_DENIED;
00123         }
00124 
00125         unistr2_to_ascii(dfspath, &q_u->path, sizeof(dfspath)-1);
00126         if(q_u->ptr0_server) {
00127                 unistr2_to_ascii(servername, &q_u->server, sizeof(servername)-1);
00128         }
00129 
00130         if(q_u->ptr0_share) {
00131                 unistr2_to_ascii(sharename, &q_u->share, sizeof(sharename)-1);
00132         }
00133 
00134         if(q_u->ptr0_server && q_u->ptr0_share) {
00135                 pstrcpy(altpath, servername);
00136                 pstrcat(altpath, "\\");
00137                 pstrcat(altpath, sharename);
00138                 strlower_m(altpath);
00139         }
00140 
00141         DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
00142                 dfspath, servername, sharename));
00143 
00144         if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, dfspath, &jn, &consumedcnt, &self_ref))) {
00145                 return WERR_DFS_NO_SUCH_VOL;
00146         }
00147 
00148         /* if no server-share pair given, remove the msdfs link completely */
00149         if(!q_u->ptr0_server && !q_u->ptr0_share) {
00150                 if(!remove_msdfs_link(&jn)) {
00151                         vfs_ChDir(p->conn,p->conn->connectpath);
00152                         return WERR_DFS_NO_SUCH_VOL;
00153                 }
00154                 vfs_ChDir(p->conn,p->conn->connectpath);
00155         } else {
00156                 int i=0;
00157                 /* compare each referral in the list with the one to remove */
00158                 DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count));
00159                 for(i=0;i<jn.referral_count;i++) {
00160                         pstring refpath;
00161                         pstrcpy(refpath,jn.referral_list[i].alternate_path);
00162                         trim_char(refpath, '\\', '\\');
00163                         DEBUG(10,("_dfs_remove:  refpath: .%s.\n", refpath));
00164                         if(strequal(refpath, altpath)) {
00165                                 *(jn.referral_list[i].alternate_path)='\0';
00166                                 DEBUG(10,("_dfs_remove: Removal request matches referral %s\n",
00167                                         refpath));
00168                                 found = True;
00169                         }
00170                 }
00171 
00172                 if(!found) {
00173                         return WERR_DFS_NO_SUCH_SHARE;
00174                 }
00175 
00176                 /* Only one referral, remove it */
00177                 if(jn.referral_count == 1) {
00178                         if(!remove_msdfs_link(&jn)) {
00179                                 vfs_ChDir(p->conn,p->conn->connectpath);
00180                                 return WERR_DFS_NO_SUCH_VOL;
00181                         }
00182                 } else {
00183                         if(!create_msdfs_link(&jn, True)) { 
00184                                 vfs_ChDir(p->conn,p->conn->connectpath);
00185                                 return WERR_DFS_CANT_CREATE_JUNCT;
00186                         }
00187                 }
00188                 vfs_ChDir(p->conn,p->conn->connectpath);
00189         }
00190 
00191         return WERR_OK;
00192 }
00193 
00194 static BOOL init_reply_dfs_info_1(struct junction_map* j, NETDFS_DFS_INFO1* dfs1)
00195 {
00196         pstring str;
00197         dfs1->ptr0_path = 1;
00198         slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(), 
00199                 j->service_name, j->volume_name);
00200         DEBUG(5,("init_reply_dfs_info_1: initing entrypath: %s\n",str));
00201         init_unistr2(&dfs1->path,str,UNI_STR_TERMINATE);
00202         return True;
00203 }
00204 
00205 static BOOL init_reply_dfs_info_2(struct junction_map* j, NETDFS_DFS_INFO2* dfs2)
00206 {
00207         pstring str;
00208         dfs2->ptr0_path = 1;
00209         slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
00210                 j->service_name, j->volume_name);
00211         init_unistr2(&dfs2->path, str, UNI_STR_TERMINATE);
00212         dfs2->ptr0_comment = 0;
00213         init_unistr2(&dfs2->comment, j->comment, UNI_STR_TERMINATE);
00214         dfs2->state = 1; /* set up state of dfs junction as OK */
00215         dfs2->num_stores = j->referral_count;
00216         return True;
00217 }
00218 
00219 static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, NETDFS_DFS_INFO3* dfs3)
00220 {
00221         int ii;
00222         pstring str;
00223         dfs3->ptr0_path = 1;
00224         if (j->volume_name[0] == '\0')
00225                 slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s",
00226                         global_myname(), j->service_name);
00227         else
00228                 slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname(),
00229                         j->service_name, j->volume_name);
00230 
00231         init_unistr2(&dfs3->path, str, UNI_STR_TERMINATE);
00232         dfs3->ptr0_comment = 1;
00233         init_unistr2(&dfs3->comment, j->comment, UNI_STR_TERMINATE);
00234         dfs3->state = 1;
00235         dfs3->num_stores = dfs3->size_stores = j->referral_count;
00236     
00237         /* also enumerate the stores */
00238         if (j->referral_count) {
00239                 dfs3->stores = TALLOC_ARRAY(ctx, NETDFS_DFS_STORAGEINFO, j->referral_count);
00240                 if (!dfs3->stores)
00241                         return False;
00242                 memset(dfs3->stores, '\0', j->referral_count * sizeof(NETDFS_DFS_STORAGEINFO));
00243                 dfs3->ptr0_stores = 1;
00244         } else {
00245                 dfs3->stores = NULL;
00246                 dfs3->ptr0_stores = 0;
00247         }
00248 
00249         for(ii=0;ii<j->referral_count;ii++) {
00250                 char* p; 
00251                 pstring path;
00252                 NETDFS_DFS_STORAGEINFO* stor = &(dfs3->stores[ii]);
00253                 struct referral* ref = &(j->referral_list[ii]);
00254   
00255                 pstrcpy(path, ref->alternate_path);
00256                 trim_char(path,'\\','\0');
00257                 p = strrchr_m(path,'\\');
00258                 if(p==NULL) {
00259                         DEBUG(4,("init_reply_dfs_info_3: invalid path: no \\ found in %s\n",path));
00260                         continue;
00261                 }
00262                 *p = '\0';
00263                 DEBUG(5,("storage %d: %s.%s\n",ii,path,p+1));
00264                 stor->state = 2; /* set all stores as ONLINE */
00265                 init_unistr2(&stor->server, path, UNI_STR_TERMINATE);
00266                 init_unistr2(&stor->share,  p+1, UNI_STR_TERMINATE);
00267                 stor->ptr0_server = stor->ptr0_share = 1;
00268         }
00269         return True;
00270 }
00271 
00272 static BOOL init_reply_dfs_info_100(struct junction_map* j, NETDFS_DFS_INFO100* dfs100)
00273 {
00274         dfs100->ptr0_comment = 1;
00275         init_unistr2(&dfs100->comment, j->comment, UNI_STR_TERMINATE);
00276         return True;
00277 }
00278 
00279 
00280 WERROR _dfs_Enum(pipes_struct *p, NETDFS_Q_DFS_ENUM *q_u, NETDFS_R_DFS_ENUM *r_u)
00281 {
00282         uint32 level = q_u->level;
00283         struct junction_map jn[MAX_MSDFS_JUNCTIONS];
00284         int num_jn = 0;
00285         int i;
00286 
00287         num_jn = enum_msdfs_links(p->mem_ctx, jn, ARRAY_SIZE(jn));
00288         vfs_ChDir(p->conn,p->conn->connectpath);
00289     
00290         DEBUG(5,("_dfs_Enum: %d junctions found in Dfs, doing level %d\n", num_jn, level));
00291 
00292         r_u->ptr0_info = q_u->ptr0_info;
00293         r_u->ptr0_total = q_u->ptr0_total;
00294         r_u->total = num_jn;
00295 
00296         r_u->info = q_u->info;
00297 
00298         /* Create the return array */
00299         switch (level) {
00300         case 1:
00301                 r_u->info.e.u.info1.count = num_jn;
00302                 if (num_jn) {
00303                         if ((r_u->info.e.u.info1.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO1, num_jn)) == NULL) {
00304                                 return WERR_NOMEM;
00305                         }
00306                         r_u->info.e.u.info1.ptr0_s = 1;
00307                         r_u->info.e.u.info1.size_s = num_jn;
00308                 }
00309                 break;
00310         case 2:
00311                 r_u->info.e.u.info2.count = num_jn;
00312                 if (num_jn) {
00313                         if ((r_u->info.e.u.info2.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO2, num_jn)) == NULL) {
00314                                 return WERR_NOMEM;
00315                         }
00316                         r_u->info.e.u.info2.ptr0_s = 1;
00317                         r_u->info.e.u.info2.size_s = num_jn;
00318                 }
00319                 break;
00320         case 3:
00321                 r_u->info.e.u.info3.count = num_jn;
00322                 if (num_jn) {
00323                         if ((r_u->info.e.u.info3.s = TALLOC_ARRAY(p->mem_ctx, NETDFS_DFS_INFO3, num_jn)) == NULL) {
00324                                 return WERR_NOMEM;
00325                         }
00326                         r_u->info.e.u.info3.ptr0_s = 1;
00327                         r_u->info.e.u.info3.size_s = num_jn;
00328                 }
00329                 break;
00330         default:
00331                 return WERR_INVALID_PARAM;
00332         }
00333 
00334         for (i = 0; i < num_jn; i++) {
00335                 switch (level) {
00336                 case 1: 
00337                         init_reply_dfs_info_1(&jn[i], &r_u->info.e.u.info1.s[i]);
00338                         break;
00339                 case 2:
00340                         init_reply_dfs_info_2(&jn[i], &r_u->info.e.u.info2.s[i]);
00341                         break;
00342                 case 3:
00343                         init_reply_dfs_info_3(p->mem_ctx, &jn[i], &r_u->info.e.u.info3.s[i]);
00344                         break;
00345                 default:
00346                         return WERR_INVALID_PARAM;
00347                 }
00348         }
00349   
00350         r_u->status = WERR_OK;
00351 
00352         return r_u->status;
00353 }
00354       
00355 WERROR _dfs_GetInfo(pipes_struct *p, NETDFS_Q_DFS_GETINFO *q_u, 
00356                      NETDFS_R_DFS_GETINFO *r_u)
00357 {
00358         UNISTR2* uni_path = &q_u->path;
00359         uint32 level = q_u->level;
00360         int consumedcnt = sizeof(pstring);
00361         pstring path;
00362         BOOL ret = False;
00363         BOOL self_ref = False;
00364         struct junction_map jn;
00365 
00366         unistr2_to_ascii(path, uni_path, sizeof(path)-1);
00367         if(!create_junction(path, &jn))
00368                 return WERR_DFS_NO_SUCH_SERVER;
00369   
00370         /* The following call can change the cwd. */
00371         if(!NT_STATUS_IS_OK(get_referred_path(p->mem_ctx, path, &jn, &consumedcnt, &self_ref)) || consumedcnt < strlen(path)) {
00372                 vfs_ChDir(p->conn,p->conn->connectpath);
00373                 return WERR_DFS_NO_SUCH_VOL;
00374         }
00375 
00376         vfs_ChDir(p->conn,p->conn->connectpath);
00377         r_u->info.switch_value = level;
00378         r_u->info.ptr0 = 1;
00379         r_u->status = WERR_OK;
00380 
00381         switch (level) {
00382                 case 1: ret = init_reply_dfs_info_1(&jn, &r_u->info.u.info1); break;
00383                 case 2: ret = init_reply_dfs_info_2(&jn, &r_u->info.u.info2); break;
00384                 case 3: ret = init_reply_dfs_info_3(p->mem_ctx, &jn, &r_u->info.u.info3); break;
00385                 case 100: ret = init_reply_dfs_info_100(&jn, &r_u->info.u.info100); break;
00386                 default:
00387                         r_u->info.ptr0 = 1;
00388                         r_u->info.switch_value = 0;
00389                         r_u->status = WERR_OK;
00390                         ret = True;
00391                         break;
00392         }
00393 
00394         if (!ret) 
00395                 r_u->status = WERR_INVALID_PARAM;
00396   
00397         return r_u->status;
00398 }
00399 
00400 WERROR _dfs_SetInfo(pipes_struct *p, NETDFS_Q_DFS_SETINFO *q_u, NETDFS_R_DFS_SETINFO *r_u)
00401 {
00402         /* FIXME: Implement your code here */
00403         return WERR_NOT_SUPPORTED;
00404 }
00405 
00406 WERROR _dfs_Rename(pipes_struct *p, NETDFS_Q_DFS_RENAME *q_u, NETDFS_R_DFS_RENAME *r_u)
00407 {
00408         /* FIXME: Implement your code here */
00409         return WERR_NOT_SUPPORTED;
00410 }
00411 
00412 WERROR _dfs_Move(pipes_struct *p, NETDFS_Q_DFS_MOVE *q_u, NETDFS_R_DFS_MOVE *r_u)
00413 {
00414         /* FIXME: Implement your code here */
00415         return WERR_NOT_SUPPORTED;
00416 }
00417 
00418 WERROR _dfs_ManagerGetConfigInfo(pipes_struct *p, NETDFS_Q_DFS_MANAGERGETCONFIGINFO *q_u, NETDFS_R_DFS_MANAGERGETCONFIGINFO *r_u)
00419 {
00420         /* FIXME: Implement your code here */
00421         return WERR_NOT_SUPPORTED;
00422 }
00423 
00424 WERROR _dfs_ManagerSendSiteInfo(pipes_struct *p, NETDFS_Q_DFS_MANAGERSENDSITEINFO *q_u, NETDFS_R_DFS_MANAGERSENDSITEINFO *r_u)
00425 {
00426         /* FIXME: Implement your code here */
00427         return WERR_NOT_SUPPORTED;
00428 }
00429 
00430 WERROR _dfs_AddFtRoot(pipes_struct *p, NETDFS_Q_DFS_ADDFTROOT *q_u, NETDFS_R_DFS_ADDFTROOT *r_u)
00431 {
00432         /* FIXME: Implement your code here */
00433         return WERR_NOT_SUPPORTED;
00434 }
00435 
00436 WERROR _dfs_RemoveFtRoot(pipes_struct *p, NETDFS_Q_DFS_REMOVEFTROOT *q_u, NETDFS_R_DFS_REMOVEFTROOT *r_u)
00437 {
00438         /* FIXME: Implement your code here */
00439         return WERR_NOT_SUPPORTED;
00440 }
00441 
00442 WERROR _dfs_AddStdRoot(pipes_struct *p, NETDFS_Q_DFS_ADDSTDROOT *q_u, NETDFS_R_DFS_ADDSTDROOT *r_u)
00443 {
00444         /* FIXME: Implement your code here */
00445         return WERR_NOT_SUPPORTED;
00446 }
00447 
00448 WERROR _dfs_RemoveStdRoot(pipes_struct *p, NETDFS_Q_DFS_REMOVESTDROOT *q_u, NETDFS_R_DFS_REMOVESTDROOT *r_u)
00449 {
00450         /* FIXME: Implement your code here */
00451         return WERR_NOT_SUPPORTED;
00452 }
00453 
00454 WERROR _dfs_ManagerInitialize(pipes_struct *p, NETDFS_Q_DFS_MANAGERINITIALIZE *q_u, NETDFS_R_DFS_MANAGERINITIALIZE *r_u)
00455 {
00456         /* FIXME: Implement your code here */
00457         return WERR_NOT_SUPPORTED;
00458 }
00459 
00460 WERROR _dfs_AddStdRootForced(pipes_struct *p, NETDFS_Q_DFS_ADDSTDROOTFORCED *q_u, NETDFS_R_DFS_ADDSTDROOTFORCED *r_u)
00461 {
00462         /* FIXME: Implement your code here */
00463         return WERR_NOT_SUPPORTED;
00464 }
00465 
00466 WERROR _dfs_GetDcAddress(pipes_struct *p, NETDFS_Q_DFS_GETDCADDRESS *q_u, NETDFS_R_DFS_GETDCADDRESS *r_u)
00467 {
00468         /* FIXME: Implement your code here */
00469         return WERR_NOT_SUPPORTED;
00470 }
00471 
00472 WERROR _dfs_SetDcAddress(pipes_struct *p, NETDFS_Q_DFS_SETDCADDRESS *q_u, NETDFS_R_DFS_SETDCADDRESS *r_u)
00473 {
00474         /* FIXME: Implement your code here */
00475         return WERR_NOT_SUPPORTED;
00476 }
00477 
00478 WERROR _dfs_FlushFtTable(pipes_struct *p, NETDFS_Q_DFS_FLUSHFTTABLE *q_u, NETDFS_R_DFS_FLUSHFTTABLE *r_u)
00479 {
00480         /* FIXME: Implement your code here */
00481         return WERR_NOT_SUPPORTED;
00482 }
00483 
00484 WERROR _dfs_Add2(pipes_struct *p, NETDFS_Q_DFS_ADD2 *q_u, NETDFS_R_DFS_ADD2 *r_u)
00485 {
00486         /* FIXME: Implement your code here */
00487         return WERR_NOT_SUPPORTED;
00488 }
00489 
00490 WERROR _dfs_Remove2(pipes_struct *p, NETDFS_Q_DFS_REMOVE2 *q_u, NETDFS_R_DFS_REMOVE2 *r_u)
00491 {
00492         /* FIXME: Implement your code here */
00493         return WERR_NOT_SUPPORTED;
00494 }
00495 
00496 WERROR _dfs_EnumEx(pipes_struct *p, NETDFS_Q_DFS_ENUMEX *q_u, NETDFS_R_DFS_ENUMEX *r_u)
00497 {
00498         /* FIXME: Implement your code here */
00499         return WERR_NOT_SUPPORTED;
00500 }
00501 
00502 WERROR _dfs_SetInfo2(pipes_struct *p, NETDFS_Q_DFS_SETINFO2 *q_u, NETDFS_R_DFS_SETINFO2 *r_u)
00503 {
00504         /* FIXME: Implement your code here */
00505         return WERR_NOT_SUPPORTED;
00506 }

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